[#16963] Refactor page nav and fix its API (#17031)

* Refactor page-nav and fix API

* Update and fix page-nav in scroll-page component

* Update page-nav uses in quo-preview

* Update page-nav uses in syncing

* Update page-nav uses in communities

* Update page-nav uses in wallet

* Update page-nav uses in onboarding
This commit is contained in:
Ulises Manuel 2023-08-28 03:44:53 -06:00 committed by GitHub
parent 6870000490
commit 6156bfc472
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 793 additions and 602 deletions

View File

@ -1,262 +0,0 @@
(ns quo2.components.navigation.page-nav
(:require [clojure.string :as string]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.buttons.button.view :as button]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[quo2.theme :as theme]))
(def ^:private centrify-style
{:display :flex
:justify-content :center
:align-items :center})
(def ^:private align-left (assoc centrify-style :align-items :flex-start))
(defn- big? [size] (= size :big))
(defn- icon-props
[color size]
(merge {:size 20
:container-style {:width (if (big? size)
20
16)
:height (if (big? size)
20
16)}}
(if-not (string/blank? color)
{:color color}
{:no-color true})))
(defn left-section-view
[{:keys [on-press icon accessibility-label type icon-background]
:or {type :grey}}
put-middle-section-on-left?]
[rn/view {:style (when put-middle-section-on-left? {:margin-right 5})}
[button/button
{:on-press on-press
:icon-only? true
:type type
:size 32
:accessibility-label accessibility-label
:background icon-background}
icon]])
(defn- mid-section-comp
[{:keys [description-img description-user-icon horizontal-description?
text-secondary-color align-mid? text-color icon main-text type description]}]
[rn/view
{:style (assoc centrify-style
:flex-direction :row
:margin-horizontal 2)}
(when (or (and (not horizontal-description?)
align-mid?
(not= :text-with-description type))
(and (or description-img description-user-icon)
(not icon)))
(if description-img
[rn/view {:margin-right 8}
[description-img]]
[rn/image
{:source {:uri description-user-icon}
:style {:width 32
:height 32
:border-radius 32
:margin-right 8}}]))
[rn/view
{:style {:flex-direction (if horizontal-description?
:row
:column)}}
[text/text
{:size :paragraph-1
:weight :semi-bold
:style {:color text-color
:line-height 21}}
main-text]
(when description
[text/text
{:size :paragraph-2
:weight :medium
:style (cond-> {:padding-right 4
:color text-secondary-color
:line-height 18}
horizontal-description? (assoc :margin-left 4 :margin-top 2))}
description])]])
(defn- mid-section-view
[{:keys [horizontal-description? one-icon-align-left? type left-align?
main-text right-icon main-text-icon-color left-icon on-press avatar theme]
:as props}]
(let [text-color (colors/theme-colors colors/neutral-95 colors/neutral-5 theme)
text-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
component-instance [mid-section-comp (assoc props :text-secondary-color text-secondary-color)]]
[rn/touchable-opacity {:on-press on-press}
[rn/view
{:style (merge
(if left-align?
align-left
centrify-style)
{:flex 1
:margin-left 4
:text-align-vertical :center})}
(case type
:text-only [text/text
{:size :paragraph-1
:weight :semi-bold
:style {:color text-color}}
main-text]
:user-avatar [rn/view {:style (assoc centrify-style :flex-direction :row)}
[user-avatar/user-avatar avatar]
[text/text
{:size :paragraph-1
:weight :semi-bold
:style {:padding-horizontal 4
:color text-color}}
main-text]]
:text-with-two-icons [rn/view {:style (assoc centrify-style :flex-direction :row)}
[icons/icon left-icon
(icon-props main-text-icon-color :big)]
[text/text
{:size :paragraph-1
:weight :semi-bold
:style {:padding-horizontal 4
:color text-color}}
main-text]
[icons/icon right-icon
(icon-props main-text-icon-color :big)]]
:text-with-one-icon [rn/view {:style {:flex-direction :row}}
(if one-icon-align-left?
[rn/view
{:style {:flex-direction :row
:align-items :center}}
(when horizontal-description?
[icons/icon left-icon
(icon-props main-text-icon-color :big)])
component-instance]
[rn/view
{:style {:flex-direction :row
:align-items :center}}
component-instance
(when horizontal-description?
[icons/icon left-icon
(icon-props main-text-icon-color :big)])])]
:text-with-description component-instance)]]))
(defn- right-section-view
[right-section-buttons]
[rn/view
{:style (assoc centrify-style
:flex-direction :row
:justify-content :flex-end)}
(let [last-icon-index (-> right-section-buttons count dec)]
(map-indexed (fn [index
{:keys [icon on-press type style icon-background
accessibility-label label]
:or {type :grey}}]
^{:key index}
[rn/view
(cond-> {:style (assoc style
:margin-right
(if (= index last-icon-index) 0 8))}
accessibility-label (assoc :accessibility-label accessibility-label
:accessible true))
[button/button
{:on-press on-press
:icon-only? (not label)
:type type
:icon-left (when label icon)
:size 32
:background icon-background}
(if label label icon)]])
right-section-buttons))])
(defn- page-nav-internal
"[page-nav opts]
opts
{ :one-icon-align-left? true/false
:horizontal-description? true/false
:align-mid? true/false
:page-nav-color color
:page-nav-background-uri image-uri
:mid-section
{:type one-of :text-only :text-with-two-icons :text-with-one-icon :text-with-description :user-avatar
:icon icon
:main-text string
:left-icon icon
:right-icon icon
:description string
:description-color color
:description-icon icon
:description-user-icon icon
:description-img a render prop which will be used in place of :description-user-icon
:main-text-icon-color color
}
:left-section
{:type button-type
:on-press event
:icon icon
}
:right-section-buttons vector of
{:type button-type
:on-press event
:icon icon
}
:theme :light or :dark
}
"
[{:keys [container-style one-icon-align-left? horizontal-description?
align-mid? page-nav-color page-nav-background-uri
mid-section
left-section
right-section-buttons
theme]}]
(let [put-middle-section-on-left? (or align-mid?
(> (count right-section-buttons) 1))
mid-section-props
{:type (:type mid-section)
:theme theme
:horizontal-description? horizontal-description?
:description-img (:description-img mid-section)
:main-text (:main-text mid-section)
:main-text-icon-color (:main-text-icon-color mid-section)
:one-icon-align-left? one-icon-align-left?
:right-icon (:right-icon mid-section)
:icon (:icon mid-section)
:left-icon (:left-icon mid-section)
:avatar (:avatar mid-section)}]
[rn/view
{:style (cond-> (merge {:display :flex
:flex-direction :row
;; iPhone 11 Pro's height in Figma divided by Component height 56/1125
:align-items :center
:padding-horizontal 20
:height 56
:justify-content :space-between}
container-style)
page-nav-background-uri (assoc :background-color page-nav-color)
page-nav-color (assoc :background page-nav-background-uri))}
[rn/view
{:style {:flex 1
:flex-direction :row
:align-items :center}}
(when left-section
[left-section-view left-section put-middle-section-on-left?])
(when mid-section
(cond
put-middle-section-on-left?
[mid-section-view
(assoc mid-section-props
:left-align? true
:description (:description mid-section)
:description-color (:description-color mid-section)
:description-icon (:description-icon mid-section)
:align-mid? align-mid?
:description-user-icon (:description-user-icon mid-section))]
(not put-middle-section-on-left?)
[mid-section-view mid-section-props]))]
[right-section-view right-section-buttons]]))
(def page-nav (theme/with-theme page-nav-internal))

View File

@ -0,0 +1,90 @@
(ns quo2.components.navigation.page-nav.style
(:require [quo2.foundations.colors :as colors]))
(defn container
[margin-top]
{:margin-top margin-top
:padding-horizontal 20
:padding-vertical 12
:height 56
:flex-direction :row
:justify-content :space-between
:align-items :center})
(defn center-content-container
[centered?]
{:flex 1
:margin-horizontal 12
:flex-direction :row
:align-items :center
:justify-content (if centered? :center :flex-start)})
(def account-switcher-placeholder
{:width 32
:height 32
:border-radius 10
:background-color (colors/custom-color :purple 50)})
(def right-actions-container
{:flex-direction :row})
(def right-actions-spacing
{:width 12})
(def right-content-min-size
{:min-width 32 :min-height 32})
(def token-logo
{:width 16 :height 16})
(def token-name
{:margin-left 4
:text-align-vertical :center})
(defn token-abbreviation
[theme background]
(let [color (case background
:photo nil
:blur (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-40 theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))]
{:margin-left 4
:color color
:text-align-vertical :center}))
(def channel-emoji
{:width 20 :height 20})
(defn channel-icon-color
[theme background]
(case background
:photo nil
:blur (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(def channel-name
{:margin-horizontal 4
:text-align-vertical :center})
(def group-avatar-picture
{:margin-right 8})
(def title-description-container
{:height 32
:justify-content :center})
(def title-description-title
{:text-align-vertical :center})
(defn title-description-description
[theme background]
(let [color (case background
:photo (colors/theme-colors colors/neutral-80-opa-80-blur colors/white-opa-70 theme)
:blur (colors/theme-colors colors/neutral-80-opa-50 colors/white-opa-40 theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))]
{:color color
:text-align-vertical :center}))
(def community-network-logo
{:width 24
:height 24
:margin-right 6})

View File

@ -0,0 +1,285 @@
(ns quo2.components.navigation.page-nav.view
(:require [quo2.components.avatars.group-avatar.view :as group-avatar]
[quo2.components.buttons.button.view :as button]
[quo2.components.dropdowns.dropdown :as dropdown]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.components.navigation.page-nav.style :as style]
[quo2.theme :as theme]
[react-native.core :as rn]))
(def ^:private button-type
{:white :grey
:neutral-5 :dark-grey
:neutral-90 :grey
:neutral-95 :dark-grey
:neutral-100 :black
:photo :grey
:blur :grey})
(defn- page-nav-base
[{:keys [margin-top background on-press accessibility-label icon-name]
:or {background :white}}
& children]
(into [rn/view {:style (style/container margin-top)}
(when icon-name
[button/button
{:type (button-type background)
:icon-only? true
:size 32
:on-press on-press
:accessibility-label accessibility-label
:background (when (#{:photo :blur} background) background)}
icon-name])]
children))
(defn- right-section-spacing [] [rn/view {:style style/right-actions-spacing}])
(defn- add-right-buttons-xf
[max-actions background]
(comp (filter map?)
(take max-actions)
(map (fn [{:keys [icon-name label] :as button-props}]
[button/button
(assoc button-props
:type (button-type background)
:icon-only? icon-name
:size 32
:accessible true
:background (when (#{:photo :blur} background) background))
(or label icon-name)]))
(interpose [right-section-spacing])))
(defn- right-content
[{:keys [background content max-actions min-size? support-account-switcher?]
:or {support-account-switcher? true}}]
[rn/view (when min-size? {:style style/right-content-min-size})
(cond
;; TODO: use account-switcher when available (issue #16456)
(and support-account-switcher? (= content :account-switcher))
[rn/view {:style style/account-switcher-placeholder}]
(coll? content)
(into [rn/view {:style style/right-actions-container}]
(add-right-buttons-xf max-actions background)
content)
:else
nil)])
(defn- title-center
[{:keys [centered? title]}]
[rn/view {:style (style/center-content-container centered?)}
[text/text
{:weight :medium
:size :paragraph-1
:number-of-lines 1}
title]])
(defn- dropdown-center
[{:keys [theme background dropdown-on-change dropdown-selected? dropdown-text]}]
(let [dropdown-type (cond
(= background :photo) :grey
(and (= theme :dark) (= background :blur)) :grey
:else :ghost)]
[rn/view {:style (style/center-content-container true)}
[dropdown/dropdown
{:type dropdown-type
:size 32
:on-change dropdown-on-change
:selected dropdown-selected?}
dropdown-text]]))
(defn- token-center
[{:keys [theme background token-logo token-name token-abbreviation]}]
[rn/view {:style (style/center-content-container false)}
[rn/image {:style style/token-logo :source token-logo}]
[text/text
{:style style/token-name
:weight :semi-bold
:size :paragraph-1
:number-of-lines 1}
token-name]
[text/text
{:style (style/token-abbreviation theme background)
:weight :medium
:size :paragraph-2
:number-of-lines 1}
token-abbreviation]])
(defn- channel-center
[{:keys [theme background channel-emoji channel-name channel-icon]}]
[rn/view {:style (style/center-content-container false)}
[rn/text {:style style/channel-emoji}
channel-emoji]
[text/text
{:style style/channel-name
:weight :semi-bold
:size :paragraph-1
:number-of-lines 1}
(str "# " channel-name)]
[icons/icon channel-icon {:size 16 :color (style/channel-icon-color theme background)}]])
(defn- title-description-center
[{:keys [background theme picture title description]}]
[rn/view {:style (style/center-content-container false)}
(when picture
[rn/view {:style style/group-avatar-picture}
[group-avatar/view {:picture picture :size 28}]])
[rn/view {:style style/title-description-container}
[text/text
{:style style/title-description-title
:weight :semi-bold
:size :paragraph-1
:number-of-lines 1}
title]
[text/text
{:style (style/title-description-description theme background)
:weight :medium
:size :paragraph-2
:number-of-lines 1}
description]]])
(defn- community-network-center
[{:keys [type community-logo network-logo community-name network-name]}]
(let [community? (= type :community)
shown-logo (if community? community-logo network-logo)
shown-name (if community? community-name network-name)]
[rn/view {:style (style/center-content-container false)}
[rn/image
{:style style/community-network-logo
:source shown-logo}]
[text/text
{:weight :semi-bold
:size :paragraph-1
:number-of-lines 1}
shown-name]]))
(defn- view-internal
[{:keys [type right-side background text-align]
:or {type :no-title
text-align :center
right-side :none
background :white}
:as props}]
(case type
:no-title
[page-nav-base props
[right-content {:background background :content right-side :max-actions 3}]]
:title
(let [centered? (= text-align :center)]
[page-nav-base props
[title-center (assoc props :centered? centered?)]
[right-content
{:background background
:content right-side
:max-actions (if centered? 1 3)
:min-size? centered?}]])
:dropdown
[page-nav-base props
[dropdown-center props]
[rn/view {:style style/right-actions-container}
(let [{button-icon :icon-name :as button-props} (first right-side)]
[button/button
(assoc button-props
:type (button-type background)
:icon-only? true
:size 32
:accessible true)
button-icon])]]
:token
[page-nav-base props
[token-center props]
[right-content {:background background :content right-side :max-actions 3}]]
:channel
[page-nav-base props
[channel-center props]
[right-content
{:background background
:content right-side
:max-actions 3
:support-account-switcher? false}]]
:title-description
[page-nav-base props
[title-description-center props]
[right-content
{:background background
:content right-side
:max-actions 2
:support-account-switcher? false}]]
:wallet-networks
[page-nav-base props
;; TODO: use wallet-networks when available (issue #16946)
[rn/view {:style (style/center-content-container true)}
[text/text
{:weight :regular
:size :paragraph-1
:number-of-lines 1}
"NETWORK DROPDOWN"]]
[right-content
{:background background
:content right-side
:max-actions 1
:min-size? true}]]
(:community :network)
[page-nav-base props
[community-network-center props]
[right-content
{:background background
:content right-side
:max-actions 3
:support-account-switcher? false}]]
nil))
(def page-nav
"Props:
- type: defaults to `:no-title`.
- background:
`:white`, `:neutral-5`, `:neutral-90`, `:neutral-95`, `:neutral-100`, `:photo` or `:blur`
- accessibility-label
- on-press: callback for left button
- icon-name: icon for left button
- right-side (optional):
- The `:account-switcher` keyword
- vector of maps to render buttons, e.g.:
{:icon-name :i/my-icon
:on-press (fn callback [] nil)
:accessibility-label \"an optional label\"}
Depending on the `type` selected, different properties are accepted:
`:title`
- title
- text-align: `:center` or `:left`
`:dropdown`
- dropdown-on-change: a callback
- dropdown-selected?: a boolean
- dropdown-text
`:token`
- token-logo: a valid rn/image `:source` value
- token-name: string
- token-abbreviation: string
`:channel`
- channel-emoji: an emoji in a string
- channel-name
- channel-icon: an icon keyword (:i/members, :i/lock, etc.)
`:title-description`
- title
- description
- picture: a valid rn/image `:source` value
`:wallet-network`
(Not implemented yet)
`:community`
- community-name
- community-logo: a valid rn/image `:source` value
`:network`
- network-name
- network-logo a valid rn/image `:source` value"
(theme/with-theme view-internal))

View File

@ -75,7 +75,7 @@
quo2.components.messages.gap
quo2.components.messages.system-message
quo2.components.navigation.floating-shell-button.view
quo2.components.navigation.page-nav
quo2.components.navigation.page-nav.view
quo2.components.notifications.activity-log.view
quo2.components.notifications.activity-logs-photos.view
quo2.components.notifications.count-down-circle
@ -251,7 +251,7 @@
;;;; Navigation
(def floating-shell-button quo2.components.navigation.floating-shell-button.view/view)
(def page-nav quo2.components.navigation.page-nav/page-nav)
(def page-nav quo2.components.navigation.page-nav.view/page-nav)
;;;; Markdown
(def markdown-list quo2.components.markdown.list.view/view)

View File

@ -236,16 +236,14 @@
[kb-presentation/keyboard-avoiding-view {:style {:flex 1}}
[:<>
[quo2/page-nav
{:align-mid? true
:mid-section {:type :text-only
:main-text (i18n/label :t/send-transaction)}
:left-section {:on-press #(do
(re-frame/dispatch [:navigate-back])
(re-frame/dispatch
[:wallet/cancel-transaction-command]))
:icon :i/arrow-left
:accessibility-label :back-button}}]
{:type :title
:text-align :left
:title (i18n/label :t/send-transaction)
:icon-name :i/arrow-left
:on-press (fn []
(re-frame/dispatch [:navigate-back])
(re-frame/dispatch [:wallet/cancel-transaction-command]))
:accessibility-label :back-button}]
[react/scroll-view
{:style {:flex 1}
:keyboard-should-persist-taps :handled}

View File

@ -20,7 +20,7 @@
(min maximum)))
(defn f-scroll-page-header
[scroll-height height name page-nav logo sticky-header top-nav title-colum navigate-back?]
[scroll-height height name page-nav-right-side logo sticky-header top-nav title-colum navigate-back?]
(let [input-range (if platform/ios? [-47 10] [0 10])
output-range (if platform/ios? [-208 0] [-208 -45])
y (reanimated/use-shared-value scroll-height)
@ -64,26 +64,15 @@
(if top-nav
[rn/view {:style {:margin-top (if platform/ios? 44 0)}}
top-nav]
[rn/view {:style {:margin-top 44}}
[quo/page-nav
(merge
{:horizontal-description? true
:one-icon-align-left? true
:align-mid? false
:page-nav-color :transparent
:mid-section {:type :text-with-description
:main-text nil
:description-img nil}
:right-section-buttons (if (= 1 reanimated/get-shared-value opacity-animation)
(assoc page-nav :icon-background :blur)
page-nav)}
(when navigate-back?
{:left-section {:icon :i/close
:type :grey
:icon-background (if (= 1 reanimated/get-shared-value opacity-animation)
:blur
:photo)
:on-press #(rf/dispatch [:navigate-back])}}))]])
[quo/page-nav
(cond-> {:margin-top 44
:type :no-title
:background (if (= 1 (reanimated/get-shared-value opacity-animation))
:blur
:photo)
:right-side page-nav-right-side}
navigate-back? (assoc :icon-name :i/close
:on-press #(rf/dispatch [:navigate-back])))])
(when title-colum
title-colum)
sticky-header]]))

View File

@ -297,14 +297,11 @@
(defn page-nav-right-section-buttons
[id]
[{:icon :i/options
:type :grey
:icon-background :photo
[{:icon-name :i/options
:accessibility-label :community-options-for-community
:on-press #(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[options/community-options-bottom-sheet id])}])}])
{:content (fn [] [options/community-options-bottom-sheet id])}])}])
(defn pick-first-category-by-height
[scroll-height first-channel-height categories-heights]

View File

@ -1,21 +0,0 @@
(ns status-im2.contexts.onboarding.common.navigation-bar.view
(:require [quo2.core :as quo]
[react-native.core :as rn]
[utils.re-frame :as rf]))
(defn navigation-bar
[{:keys [top right-section-buttons disable-back-button? stack-id]}]
(let [back-event (if stack-id [:navigate-back-within-stack stack-id] [:navigate-back])]
[rn/view
{:style {:height 56
:margin-top top}}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}
:left-section {:type :grey
:icon-background :blur
:icon :i/arrow-left
:on-press (fn []
(when-not disable-back-button?
(rf/dispatch back-event)))}
:right-section-buttons right-section-buttons}]]))

View File

@ -1,16 +1,14 @@
(ns status-im2.contexts.onboarding.create-password.view
(:require
[oops.core :refer [ocall]]
[quo2.core :as quo]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
[status-im2.contexts.onboarding.create-password.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]
[utils.string :as utils.string]))
(:require [oops.core :refer [ocall]]
[quo2.core :as quo]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[status-im2.contexts.onboarding.create-password.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]
[utils.string :as utils.string]))
(defn header
[]
@ -214,13 +212,13 @@
:accessible false}
[rn/view {:style style/flex-fill}
[rn/keyboard-avoiding-view {:style style/flex-fill}
[navigation-bar/navigation-bar
{:stack-id :new-to-status
:top top
:right-section-buttons [{:type :grey
:icon-background :blur
:icon :i/info
:on-press on-press-info}]}]
[quo/page-nav
{:margin-top top
:background :blur
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back-within-stack :new-to-status])
:right-side [{:icon-name :i/info
:on-press on-press-info}]}]
[password-form]
[rn/view {:style {:height (if-not @keyboard-shown? bottom 0)}}]]]]]
(finally

View File

@ -5,12 +5,11 @@
[quo2.foundations.colors :as colors]
[react-native.blur :as blur]
[react-native.core :as rn]
[react-native.hooks :as hooks]
[react-native.platform :as platform]
[react-native.safe-area :as safe-area]
[react-native.hooks :as hooks]
[reagent.core :as reagent]
[status-im2.constants :as c]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
[status-im2.contexts.onboarding.create-profile.style :as style]
[status-im2.contexts.onboarding.select-photo.method-menu.view :as method-menu]
[utils.i18n :as i18n]
@ -133,9 +132,11 @@
keyboard-shown
@content-scroll-y)]
[rn/view {:style style/page-container}
[navigation-bar/navigation-bar
{:stack-id :new-to-status
:top navigation-bar-top}]
[quo/page-nav
{:margin-top navigation-bar-top
:background :blur
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])}]
[rn/scroll-view
{:on-layout (fn [event]
(let [height (oops/oget event "nativeEvent.layout.height")]

View File

@ -2,14 +2,13 @@
(:require [quo2.core :as quo]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im2.contexts.onboarding.enable-biometrics.style :as style]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[status-im2.common.resources :as resources]
[status-im2.common.biometric.events :as biometric]
[status-im2.common.parallax.view :as parallax]
[status-im2.common.parallax.whitelist :as whitelist]
[status-im2.common.biometric.events :as biometric]))
[status-im2.common.resources :as resources]
[status-im2.contexts.onboarding.enable-biometrics.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn page-title
[]
@ -48,7 +47,7 @@
{:layers (:biometrics resources/parallax-video)
:stretch stretch}]
[rn/view
[navigation-bar/navigation-bar {:disable-back-button? true}]
[quo/page-nav {:background :blur}]
[page-title]]]))
(defn enable-biometrics-simple
@ -56,7 +55,7 @@
(let [width (:width (rn/get-window))]
[:<>
[rn/view {:flex 1}
[navigation-bar/navigation-bar {:disable-back-button? true}]
[quo/page-nav {:background :blur}]
[page-title]
[rn/view {:style {:flex 1}}
[rn/image

View File

@ -1,15 +1,13 @@
(ns status-im2.contexts.onboarding.enable-notifications.view
(:require
[quo2.core :as quo]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.safe-area :as safe-area]
[status-im.notifications.core :as notifications]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
[status-im2.contexts.onboarding.enable-notifications.style :as style]
[status-im2.contexts.shell.jump-to.utils :as shell.utils]))
(:require [quo2.core :as quo]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.safe-area :as safe-area]
[status-im.notifications.core :as notifications]
[status-im2.contexts.onboarding.enable-notifications.style :as style]
[status-im2.contexts.shell.jump-to.utils :as shell.utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn page-title
[]
@ -50,9 +48,10 @@
[]
(let [insets (safe-area/get-insets)]
[rn/view {:style (style/page-container insets)}
[navigation-bar/navigation-bar
{:stack-id :enable-notifications
:disable-back-button? true}]
[quo/page-nav
{:background :blur
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back-within-stack :identifiers])}]
[page-title]
[rn/view {:style style/page-illustration}
[quo/text

View File

@ -7,7 +7,6 @@
[reagent.core :as reagent]
[status-im.ethereum.mnemonic :as mnemonic]
[status-im2.constants :as constants]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
[status-im2.contexts.onboarding.enter-seed-phrase.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
@ -160,7 +159,9 @@
(let [{navigation-bar-top :top} (safe-area/get-insets)]
[rn/view {:style style/full-layout}
[rn/keyboard-avoiding-view {:style style/page-container}
[navigation-bar/navigation-bar
{:stack-id :new-to-status
:top navigation-bar-top}]
[quo/page-nav
{:margin-top navigation-bar-top
:background :blur
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back-within-stack :new-to-status])}]
[screen]]]))

View File

@ -98,37 +98,21 @@
:style style/doc-content}
(i18n/label :t/getting-started-generate-keys-on-keycard-description)]]])
(defn navigation-bar
[top]
[rn/view
{:style {:height 56
:margin-top top}}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}
:left-section {:type :grey
:icon-background :blur
:icon :i/arrow-left
:on-press navigate-back}
:right-section-buttons (cond-> [{:type :grey
:icon :i/info
:icon-background :blur
:on-press #(rf/dispatch
[:show-bottom-sheet
{:content getting-started-doc
:shell? true}])}]
config/quo-preview-enabled?
(conj {:type :grey
:icon :i/reveal-whitelist
:icon-background :blur
:on-press #(rf/dispatch [:navigate-to
:quo2-preview])}))}]])
(defn new-to-status
[]
(let [{:keys [top]} (safe-area/get-insets)]
[:<>
[rn/view {:style style/content-container}
[navigation-bar top]
[sign-in-options]]]))
[rn/view {:style style/content-container}
[quo/page-nav
{:margin-top top
:type :no-title
:background :blur
:icon-name :i/arrow-left
:on-press navigate-back
:right-side [{:icon-name :i/info
:on-press #(rf/dispatch [:show-bottom-sheet
{:content getting-started-doc
:shell? true}])}
(when config/quo-preview-enabled?
{:icon-name :i/reveal-whitelist
:on-press #(rf/dispatch [:navigate-to :quo2-preview])})]}]
[sign-in-options]]))

View File

@ -41,7 +41,7 @@
profile-color (:color (rf/sub [:onboarding-2/profile]))]
[rn/view {:style (style/page-container in-onboarding?)}
(when-not in-onboarding? [background/view true])
[quo/page-nav]
[quo/page-nav {:type :no-title :background :blur}]
[page-title (pairing-progress pairing-status)]
(if (pairing-progress pairing-status)
[rn/view {:style style/page-illustration}

View File

@ -1,14 +1,12 @@
(ns status-im2.contexts.onboarding.welcome.view
(:require
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[re-frame.core :as re-frame]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im2.constants :as constants]
[status-im2.contexts.onboarding.welcome.style :as style]))
(:require [quo2.core :as quo]
[re-frame.core :as re-frame]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im2.constants :as constants]
[status-im2.contexts.onboarding.welcome.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn page-title
[]
@ -22,22 +20,6 @@
:subtitle (i18n/label :t/welcome-to-web3-sub-title)
:subtitle-accessibility-label :welcome-sub-title}]))
(defn navigation-bar
[root]
[quo/page-nav
{:horizontal-description? false
:one-icon-align-left? true
:align-mid? false
:page-nav-color :transparent
:left-section {:icon :i/arrow-left
;TODO this is wrong - page nav needs updating
;https://github.com/status-im/status-mobile/issues/16535
; should be type:grey, and page nav can use background instead.
:icon-background-color colors/white-opa-5
:type :grey
:on-press #(rf/dispatch [:navigate-back-within-stack
root])}}])
(defn dispatch-visibility-status-update
[status-type]
(re-frame/dispatch
@ -51,7 +33,11 @@
[rn/view {:style (style/page-container insets)}
(when (nil? status-type)
(dispatch-visibility-status-update constants/visibility-status-automatic))
[navigation-bar :enable-notifications]
[quo/page-nav
{:type :no-title
:background :blur
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back-within-stack :enable-notifications])}]
[page-title]
[rn/view {:style style/page-illustration}
[quo/text

View File

@ -33,14 +33,12 @@
:favicon? false
:placeholder "Search or enter dapp domain"
:locked? false})]
[rn/keyboard-avoiding-view
{:style {:flex 1 :padding-top top}}
[rn/keyboard-avoiding-view {:style {:flex 1 :padding-top top}}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}
:left-section {:icon :i/arrow-left
:on-press
#(rf/dispatch [:navigate-back])}}]
{:type :no-title
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])}]
[rn/flat-list
{:header [preview/customizer state descriptor]
:key-fn str

View File

@ -378,19 +378,15 @@
has-profiles? (boolean (rf/sub [:profile/profiles-overview]))
root (if has-profiles? :profiles :intro)]
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only
:main-text "Quo2 components preview"}
:left-section {:icon :i/close
:on-press (fn []
(cond
logged-in?
(rf/dispatch [:navigate-back])
:else
(do
(theme/set-theme :dark)
(rf/dispatch [:init-root root]))))}}]))
{:type :title
:title "Quo2 components preview"
:text-align :left
:icon-name :i/close
:on-press #(if logged-in?
(rf/dispatch [:navigate-back])
(do
(theme/set-theme :dark)
(rf/dispatch [:init-root root])))}]))
(defn- theme-switcher
[]

View File

@ -1,132 +1,299 @@
(ns status-im2.contexts.quo-preview.navigation.page-nav
(:require [quo2.components.navigation.page-nav :as quo2]
(:require [clojure.string :as string]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.preview :as preview]))
(def ^:private descriptor
[{:label "Page nav variation"
:key :selected-variation
(def ^:private main-descriptor
[{:label "Type"
:key :type
:type :select
:options [{:key :text-only?
:value "Text only"}
{:key :align-left?
:value "Align Left"}
{:key :align-left-top-down-text?
:value "Align left top down text?"}
{:key :align-left-with-icon?
:value "Align Left with icon ?"}
{:key :one-icon-align-left?
:value "One icon on the left ?"}
{:key :one-icon-align-right?
:value "One icon on the right ?"}
{:key :two-icons?
:value "Two icons ?"}
{:key :user-icon?
:value "User icon ?"}
{:key :empty?
:value "Empty ?"}]}
{:label "Number of right icons"
:key :number-of-right-icons
:options [{:key :no-title
:value "No Title"}
{:key :title
:value "Title"}
{:key :dropdown
:value "Dropdown"}
{:key :token
:value "Token"}
{:key :channel
:value "Channel"}
{:key :title-description
:value "Title + Description"}
{:key :wallet-networks
:value "Wallet Networks"}
{:key :community
:value "Community"}
{:key :network
:value "Network"}]}
{:label "Background"
:key :background
:type :select
:options [{:key 1
:value 1}
{:key 2
:value 2}
{:key 3
:value 3}]}])
:options (map (fn [bg-type]
{:key bg-type
:value (string/capitalize (name bg-type))})
[:white :neutral-5 :neutral-90 :neutral-95 :neutral-100 :photo :blur])}
{:label "Icon"
:key :icon-name
:type :select
:options [{:key :i/placeholder
:value "Placeholder"}
{:key :i/arrow-left
:value "Arrow left"}]}])
(def ^:private selected-variation
(reagent/atom {:selected-variation :text-only?
:number-of-right-icons 1}))
(def right-side-options
(let [options [{:icon-name :i/save :on-press #(js/alert "SAVE")}
{:icon-name :i/mark-as-read :on-press #(js/alert "MARK AS READ")}
{:icon-name :i/mention :on-press #(js/alert "A MENTION!")}]]
[{:key []
:value "No actions"}
{:key (take 1 options)
:value "1 action"}
{:key (take 2 options)
:value "2 actions"}
{:key (take 3 options)
:value "3 actions"}]))
(def account-switcher
{:key :account-switcher
:value "Account-switcher"})
(def no-title-descriptor
[{:label "Right Side"
:key :right-side
:type :select
:options (conj right-side-options account-switcher)}])
(def title-descriptor
[{:label "Right Side"
:key :right-side
:type :select
:options (conj right-side-options account-switcher)}
{:label "Title"
:key :title
:type :text}
{:label "Text Align"
:key :text-align
:type :select
:options [{:key :left
:value "Left"}
{:key :center
:value "Center"}]}])
(def dropdown-descriptor
[{:label "Dropdown Selected?"
:key :dropdown-selected?
:type :boolean}
{:label "Dropdown Text"
:key :dropdown-text
:type :text}])
(def token-descriptor
[{:label "Right Side"
:key :right-side
:type :select
:options (conj right-side-options account-switcher)}
{:label "Token Logo"
:key :token-logo
:type :select
:options [{:key (resources/get-mock-image :status-logo)
:value "Status logo"}
{:key (resources/get-mock-image :rarible)
:value "Rarible"}]}
{:label "Token Name"
:key :token-name
:type :text}
{:label "Token Abbreviation"
:key :token-abbreviation
:type :text}])
(def channel-descriptor
[{:label "Right Side"
:key :right-side
:type :select
:options right-side-options}
{:label "Channel Emoji"
:key :channel-emoji
:type :select
:options [{:key "🍇"
:value "🍇"}
{:key "🍑"
:value "🍑"}]}
{:label "Channel Name"
:key :channel-name
:type :text}
{:label "Channel Icon"
:key :channel-icon
:type :select
:options [{:key :i/locked
:value "Locked"}
{:key :i/unlocked
:value "Unlocked"}]}])
(def title-description-descriptor
[{:label "Right Side"
:key :right-side
:type :select
:options (butlast right-side-options)}
{:label "title"
:key :title
:type :text}
{:label "description"
:key :description
:type :text}
{:label "Picture"
:key :picture
:type :select
:options [{:key nil
:value "No picture"}
{:key (resources/get-mock-image :photo1)
:value "Photo 1"}
{:key (resources/get-mock-image :photo2)
:value "Photo 2"}]}])
(def wallet-networks-descriptor
[{:label "Right Side"
:key :right-side
:type :select
:options (conj (take 2 right-side-options) account-switcher)}])
(def community-descriptor
[{:label "Right Side"
:key :right-side
:type :select
:options right-side-options}
{:label "Community Logo"
:key :community-logo
:type :select
:options [{:key (resources/get-mock-image :diamond)
:value "Diamond"}
{:key (resources/get-mock-image :coinbase)
:value "Coinbase"}]}
{:label "Community name"
:key :community-name
:type :text}])
(def network-descriptor
[{:label "Right Side"
:key :right-side
:type :select
:options right-side-options}
{:label "Network Logo"
:key :network-logo
:type :select
:options [{:key (resources/get-mock-image :diamond)
:value "Diamond"}
{:key (resources/get-mock-image :coinbase)
:value "Coinbase"}]}
{:label "Network name"
:key :network-name
:type :text}])
(defn- photo-bg
[background]
(when (#{:photo :blur} background)
[rn/image
{:style {:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:width "100%"
:height 200}
:source (resources/get-mock-image :photo2)}]))
(defn- blur-bg
[background]
(when (= :blur background)
[rn/view
{:style {:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:width "100%"
:height 200}}
[blur/view
{:style {:width "100%"
:height 20}
:blur-type :light
:blur-amount 20}]]))
(defn- cool-preview
[]
(let
[right-icon {:background-color (if (colors/dark?)
colors/neutral-80
colors/neutral-20)
:icon :i/placeholder
:icon-color nil}
base-props
{:horizontal-description? true
:one-icon-align-left? true
:align-mid? false
:page-nav-color :transparent
:page-nav-background-uri ""
:mid-section
{:type :text-with-description
:icon :i/placeholder
:main-text "Status"
:left-icon :i/placeholder
:right-icon :i/placeholder
:description "SNT"
:description-color "black"
:description-icon :i/placeholder
:description-user-icon
"https://i.picsum.photos/id/810/200/300.jpg?hmac=HgwlXd-OaLOAqhGyCiZDUb_75EgUI4u0GtS7nfgxd8s"}
:left-section
{:icon :i/unlocked
:icon-background-color (if (colors/dark?)
colors/neutral-80
colors/neutral-20)}}
create-variation #(merge %1 %2 {:mid-section (merge (:mid-section %1) (:mid-section %2))})
variations
{:text-only? base-props
:align-left? (create-variation base-props {:align-mid? true})
:one-icon-align-left? (create-variation base-props
{:one-icon-align-left? true
:mid-section {:type
:text-with-one-icon}})
:one-icon-align-right? (create-variation base-props
{:one-icon-align-left? false
:mid-section {:type
:text-with-one-icon}})
:two-icons? (create-variation base-props
{:mid-section {:type :text-with-two-icons}})
:user-icon? (create-variation base-props
{:align-mid? true
:horizontal-description? false
:mid-section {:type
:text-with-one-icon}})
:empty? (create-variation base-props
{:mid-section-main-text ""
:mid-section-description ""})
:align-left-with-icon? (create-variation base-props
{:align-mid? true
:mid-section {:type :text-with-one-icon}})
:align-left-top-down-text? (create-variation base-props
{:align-mid? true
:horizontal-description? false
:mid-section {:type
:text-with-description}})}
state (reagent/atom
(-> (get variations (:selected-variation @selected-variation))
(assoc :right-section-buttons
(repeat (:number-of-right-icons @selected-variation) right-icon))))]
[{:keys [theme]}]
(let [state (reagent/atom
{:type :title-description
:background (if (= theme :light) :white :neutral-90)
:icon-name :i/placeholder
:on-press #(js/alert "Left icon pressed!")
:right-side [{:icon-name :i/save :on-press #(js/alert "SAVE")}
{:icon-name :i/mark-as-read :on-press #(js/alert "MARK AS READ")}
{:icon-name :i/mention :on-press #(js/alert "A MENTION!")}]
:title "Page title"
:text-align :center
:dropdown-on-change #(js/alert "Dropdown pressed!")
:dropdown-selected? false
:dropdown-text "Recent"
:token-logo (resources/get-mock-image :status-logo)
:token-name "Status"
:token-abbreviation "SNT"
:channel-emoji "🍇"
:channel-name "general"
:channel-icon :i/locked
:description "Description"
:picture (resources/get-mock-image :photo1)
:community-name "Rarible"
:community-logo (resources/get-mock-image :coinbase)
:network-name "Mainnet"
:network-logo (resources/get-mock-image :diamond)})]
(fn []
[rn/view
{:margin-bottom 50
:padding 16}
[rn/view {:flex 1}
[preview/customizer selected-variation descriptor]]
[rn/view {:style {:margin-bottom 50 :padding-vertical 16}}
[rn/view {:style {:flex 1}}
[preview/customizer state
(concat main-descriptor
(case (:type @state)
:no-title no-title-descriptor
:title title-descriptor
:dropdown dropdown-descriptor
:token token-descriptor
:channel channel-descriptor
:title-description title-description-descriptor
:wallet-networks wallet-networks-descriptor
:community community-descriptor
:network network-descriptor
nil))]]
[rn/view
{:padding-vertical 30
:flex-direction :row
:justify-content :center}
[quo2/page-nav @state]]])))
(def ^:private trackable-cool-preview (reagent/track cool-preview selected-variation))
{:style {:background-color (case (:background @state)
:white colors/white
:neutral-5 colors/neutral-5
:neutral-90 colors/neutral-90
:neutral-95 colors/neutral-95
:neutral-100 colors/neutral-100
nil)
:padding-vertical 40
:height 200
:width "100%"}}
[photo-bg (:background @state)]
[blur-bg (:background @state)]
[quo/page-nav @state]]])))
(defn preview-page-nav
[]
[rn/view
{:background-color (colors/theme-colors colors/white
colors/neutral-90)
:flex 1}
{:style {:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [@trackable-cool-preview]
:header [(quo.theme/with-theme cool-preview)]
:key-fn str}]])

View File

@ -1,36 +1,22 @@
(ns status-im2.contexts.syncing.setup-syncing.view
(:require [utils.i18n :as i18n]
[quo2.core :as quo]
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[utils.datetime :as datetime]
[status-im2.contexts.syncing.setup-syncing.style :as style]
[utils.re-frame :as rf]
[react-native.clipboard :as clipboard]
[status-im2.contexts.syncing.sheets.enter-password.view :as enter-password]
[status-im2.common.qr-code-viewer.view :as qr-code-viewer]
[reagent.core :as reagent]
[status-im2.common.resources :as resources]
[react-native.core :as rn]
[react-native.hooks :as hooks]
[status-im2.contexts.syncing.utils :as sync-utils]))
[reagent.core :as reagent]
[status-im2.common.qr-code-viewer.view :as qr-code-viewer]
[status-im2.common.resources :as resources]
[status-im2.contexts.syncing.setup-syncing.style :as style]
[status-im2.contexts.syncing.sheets.enter-password.view :as enter-password]
[status-im2.contexts.syncing.utils :as sync-utils]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def code-valid-for-ms 120000)
(def one-min-ms 60000)
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}
:left-section {:type :grey
:icon :i/close
:on-press #(rf/dispatch [:navigate-back])}
:right-section-buttons [{:type :grey
:label (i18n/label :t/how-to-pair)
:icon :i/info
:on-press #(rf/dispatch [:open-modal :how-to-pair])}]}]])
(defn f-use-interval
[clock cleanup-clock delay]
(hooks/use-interval clock cleanup-clock delay)
@ -67,7 +53,14 @@
[rn/view {:style style/container-main}
[:f> f-use-interval clock cleanup-clock @delay]
[rn/scroll-view {}
[navigation-bar]
[quo/page-nav
{:type :no-title
:icon-name :i/close
:background :blur
:on-press #(rf/dispatch [:navigate-back])
:right-side [{:icon-left :i/info
:label (i18n/label :t/how-to-pair)
:on-press #(rf/dispatch [:open-modal :how-to-pair])}]}]
[rn/view {:style style/page-container}
[rn/view {:style style/title-container}
[quo/text

View File

@ -1,23 +1,12 @@
(ns status-im2.contexts.syncing.syncing-devices-list.view
(:require [utils.i18n :as i18n]
[quo2.core :as quo]
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im2.contexts.syncing.syncing-devices-list.style :as style]
[status-im2.contexts.syncing.device.view :as device]
[status-im2.contexts.syncing.syncing-devices-list.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}
:left-section {:type :photo
:icon-background :blur
:icon :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])}}]])
(defn view
[]
(let [devices (rf/sub [:pairing/installations])
@ -29,7 +18,11 @@
#(if (:enabled? %) :paired-devices :unpaired-devices)
other-devices)]
[rn/view {:style style/container-main}
[navigation-bar]
[quo/page-nav
{:type :no-title
:background :blur
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])}]
[rn/view {:style style/page-container}
[rn/view {:style style/title-container}
[quo/text