chore: move top nav to quo2 and align with figma (#17043)
This commit is contained in:
parent
1c730bc692
commit
d462810a57
Binary file not shown.
After Width: | Height: | Size: 217 KiB |
Binary file not shown.
After Width: | Height: | Size: 443 KiB |
Binary file not shown.
After Width: | Height: | Size: 152 KiB |
Binary file not shown.
After Width: | Height: | Size: 317 KiB |
|
@ -35,7 +35,7 @@
|
|||
:indicator-size status indicator outer radius, set to nil or 0 when no indicator
|
||||
:indicator-border `indicator-size`-`indicator-border` is the inner radius
|
||||
:indicator-color color for status indicator
|
||||
:override-theme override theme for ring
|
||||
:theme :light or :dark
|
||||
:background-color intials avatar background color
|
||||
:color intials avatar text color
|
||||
:size intials avatar radius
|
||||
|
@ -55,7 +55,7 @@
|
|||
status-indicator? true
|
||||
online? true
|
||||
ring? true
|
||||
customization-color :turquoise}
|
||||
customization-color :blue}
|
||||
:as props}]
|
||||
(let [full-name (or full-name "Your Name")
|
||||
;; image generated with profile-picture-fn is round cropped
|
||||
|
|
|
@ -4,17 +4,18 @@
|
|||
(def ^:const size 8)
|
||||
|
||||
(defn dot-background-color
|
||||
[customization-color theme]
|
||||
(if customization-color
|
||||
(colors/theme-colors
|
||||
(colors/custom-color customization-color 50)
|
||||
(colors/custom-color customization-color 60)
|
||||
theme)
|
||||
(colors/theme-colors colors/primary-50 colors/primary-60 theme)))
|
||||
[customization-color theme blur?]
|
||||
(cond
|
||||
customization-color (colors/theme-colors
|
||||
(colors/custom-color customization-color 50)
|
||||
(colors/custom-color customization-color 60)
|
||||
theme)
|
||||
blur? (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:else (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
|
||||
|
||||
(defn notification-dot
|
||||
[customization-color theme]
|
||||
{:background-color (dot-background-color customization-color theme)
|
||||
[customization-color theme blur?]
|
||||
{:background-color (dot-background-color customization-color theme blur?)
|
||||
:width size
|
||||
:height size
|
||||
:border-radius (/ size 2)
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [customization-color style theme]}]
|
||||
[{:keys [customization-color style theme blur?]}]
|
||||
[rn/view
|
||||
{:accessibility-label :notification-dot
|
||||
:style (merge
|
||||
(style/notification-dot customization-color theme)
|
||||
(style/notification-dot customization-color theme blur?)
|
||||
style)}])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
(ns quo2.components.navigation.top-nav.component-spec
|
||||
(:require [quo2.components.navigation.top-nav.view :as top-nav]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Top Nav component"
|
||||
(h/test "Renders default"
|
||||
(h/render [top-nav/view])
|
||||
(h/is-truthy (h/get-by-label-text :open-scanner-button))
|
||||
(h/is-truthy (h/get-by-label-text :open-activity-center-button))
|
||||
(h/is-truthy (h/get-by-label-text :show-qr-button))
|
||||
(h/is-truthy (h/get-by-label-text :open-profile)))
|
||||
|
||||
(h/test "On press works for all buttons and avatar"
|
||||
(let [avatar-on-press (h/mock-fn)
|
||||
scan-on-press (h/mock-fn)
|
||||
activity-center-on-press (h/mock-fn)
|
||||
qr-code-on-press (h/mock-fn)]
|
||||
|
||||
(h/render [top-nav/view
|
||||
{:avatar-on-press avatar-on-press
|
||||
:scan-on-press scan-on-press
|
||||
:activity-center-on-press activity-center-on-press
|
||||
:qr-code-on-press qr-code-on-press}])
|
||||
|
||||
(h/fire-event :press (h/get-by-label-text :open-scanner-button))
|
||||
(h/was-called scan-on-press)
|
||||
|
||||
(h/fire-event :press (h/get-by-label-text :open-activity-center-button))
|
||||
(h/was-called activity-center-on-press)
|
||||
|
||||
(h/fire-event :press (h/get-by-label-text :show-qr-button))
|
||||
(h/was-called qr-code-on-press)
|
||||
|
||||
(h/fire-event :press (h/get-by-label-text :open-profile))
|
||||
(h/was-called avatar-on-press))))
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
(ns quo2.components.navigation.top-nav.style)
|
||||
|
||||
(defn unread-indicator
|
||||
[unread-count max-value]
|
||||
(let [right-offset (cond
|
||||
(> unread-count max-value)
|
||||
-14
|
||||
;; Greater than 9 means we'll need 2 digits to represent
|
||||
;; the text.
|
||||
(> unread-count 9)
|
||||
-10
|
||||
:else -6)]
|
||||
{:position :absolute
|
||||
:top -6
|
||||
:right right-offset
|
||||
:z-index 4}))
|
||||
|
||||
(def unread-dot
|
||||
{:position :absolute
|
||||
:top -2
|
||||
:bottom 0
|
||||
:right 0
|
||||
:left 38})
|
||||
|
||||
(def right-section
|
||||
{:flex-direction :row})
|
||||
|
||||
(def top-nav-container
|
||||
{:height 56})
|
||||
|
||||
(def top-nav-inner-container
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center})
|
|
@ -0,0 +1,165 @@
|
|||
(ns quo2.components.navigation.top-nav.view
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.components.buttons.button.view :as button]
|
||||
[quo2.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo2.components.counter.counter.view :as counter]
|
||||
[quo2.components.navigation.top-nav.style :as style]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.hole-view :as hole-view]
|
||||
[quo2.components.common.notification-dot.view :as notification-dot]))
|
||||
|
||||
(def notification-dot-hole
|
||||
[{:x 37
|
||||
:y -2
|
||||
:width 9
|
||||
:height 9
|
||||
:borderRadius 4}])
|
||||
|
||||
(defn unread-counter-hole
|
||||
[notification-count]
|
||||
(let [x (case (count (str notification-count))
|
||||
(1 2) 33
|
||||
29)
|
||||
width (case (count (str notification-count))
|
||||
1 16
|
||||
2 20
|
||||
28)]
|
||||
(if (pos? (js/Number notification-count))
|
||||
[{:x x
|
||||
:y -5
|
||||
:width width
|
||||
:height 16
|
||||
:borderRadius 6}]
|
||||
nil)))
|
||||
|
||||
(defn- get-button-common-props
|
||||
[{:keys [jump-to? theme blur?]}]
|
||||
{:icon-only? true
|
||||
:size 32
|
||||
:container-style {:margin-left 12}
|
||||
:type (cond
|
||||
jump-to? :black
|
||||
(and (not blur?) (= :dark theme)) :dark-grey
|
||||
:else :grey)
|
||||
:background (when blur? :blur)})
|
||||
|
||||
(defn- unread-indicator
|
||||
[{:keys [notification-count max-value customization-color type]}]
|
||||
(when (pos? notification-count)
|
||||
[counter/view
|
||||
{:accessibility-label :activity-center-unread-count
|
||||
:type type
|
||||
:customization-color customization-color
|
||||
:container-style (style/unread-indicator notification-count
|
||||
max-value)}
|
||||
notification-count]))
|
||||
|
||||
(defn unread-dot
|
||||
[{:keys [customization-color blur? notification]}]
|
||||
[notification-dot/view
|
||||
{:style style/unread-dot
|
||||
:blur? blur?
|
||||
:customization-color (when (= notification :notification) customization-color)}])
|
||||
|
||||
(defn notification-highlight
|
||||
[{:keys [notification notification-count
|
||||
max-unread-notifications customization-color]
|
||||
:as props}]
|
||||
(case notification
|
||||
(:seen :notification) [unread-dot props]
|
||||
(:mention :mention-seen) [unread-indicator
|
||||
{:type (if (= notification :mention-seen) :grey :default)
|
||||
:notification-count notification-count
|
||||
:max-value max-unread-notifications
|
||||
:customization-color customization-color}]
|
||||
nil))
|
||||
|
||||
(defn- left-section
|
||||
[{:keys [avatar-props on-press customization-color]}]
|
||||
[rn/touchable-without-feedback {:on-press on-press}
|
||||
[rn/view
|
||||
{:accessibility-label :open-profile}
|
||||
[user-avatar/user-avatar
|
||||
(merge {:status-indicator? true
|
||||
:ring? true
|
||||
:customization-color customization-color
|
||||
:size :small}
|
||||
avatar-props)]]])
|
||||
|
||||
(defn- right-section
|
||||
[{:keys [theme
|
||||
jump-to?
|
||||
blur?
|
||||
notification
|
||||
notification-count
|
||||
activity-center-on-press
|
||||
scan-on-press
|
||||
qr-code-on-press
|
||||
for-qa-only-cellular-network
|
||||
for-qa-only-no-network
|
||||
for-qa-only-network-type]
|
||||
:as props}]
|
||||
(let [button-common-props (get-button-common-props {:theme theme
|
||||
:jump-to? jump-to?
|
||||
:blur? blur?})]
|
||||
[rn/view {:style style/right-section}
|
||||
(when (= for-qa-only-network-type "cellular")
|
||||
[button/button
|
||||
(merge (dissoc button-common-props :icon-only?)
|
||||
for-qa-only-cellular-network)
|
||||
"🦄"])
|
||||
(when (= for-qa-only-network-type "none")
|
||||
[button/button
|
||||
(merge (dissoc button-common-props :icon-only?)
|
||||
for-qa-only-no-network)
|
||||
"💀"])
|
||||
[button/button
|
||||
(assoc button-common-props :accessibility-label :open-scanner-button :on-press scan-on-press)
|
||||
:i/scan]
|
||||
[button/button
|
||||
(merge button-common-props
|
||||
{:accessibility-label :show-qr-button
|
||||
:on-press qr-code-on-press})
|
||||
:i/qr-code]
|
||||
[rn/view
|
||||
[hole-view/hole-view
|
||||
{:holes (case notification
|
||||
(:seen :notification) notification-dot-hole
|
||||
(:mention :mention-seen) (unread-counter-hole notification-count)
|
||||
nil)}
|
||||
[button/button
|
||||
(merge button-common-props
|
||||
{:accessibility-label :open-activity-center-button
|
||||
:on-press activity-center-on-press})
|
||||
:i/activity-center]]
|
||||
[notification-highlight props]]]))
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [avatar-on-press avatar-props customization-color container-style] :as props}]
|
||||
[rn/view {:style (merge style/top-nav-container container-style)}
|
||||
[rn/view {:style style/top-nav-inner-container}
|
||||
[left-section
|
||||
{:avatar-props avatar-props
|
||||
:on-press avatar-on-press
|
||||
:customization-color customization-color}]
|
||||
[right-section (dissoc props :avatar-props :avatar-on-press)]]])
|
||||
|
||||
(def view
|
||||
":container-style style map merged with outer view for margins/paddings
|
||||
:customization-color custom colors
|
||||
:blur? true/false
|
||||
:jump-to? true/false
|
||||
:theme :light/:dark
|
||||
:notification :mention/:seen/:notification (TODO :mention-seen temporarily used while resolving https://github.com/status-im/status-mobile/issues/17102 )
|
||||
:avatar-props qu2/user-avatar props
|
||||
:avatar-on-press callback
|
||||
:scan-on-press callback
|
||||
:activity-center-on-press callback
|
||||
:qr-code-on-press callback
|
||||
:notification-count number
|
||||
:max-unread-notifications used to specify max number for counter
|
||||
:for-qa-only-cellular-network used for testing purposed
|
||||
:for-qa-only-no-network used for testing purposed
|
||||
:for-qa-only-network-type used for testing purposed
|
||||
"
|
||||
(quo.theme/with-theme view-internal))
|
|
@ -76,6 +76,7 @@
|
|||
quo2.components.messages.system-message
|
||||
quo2.components.navigation.floating-shell-button.view
|
||||
quo2.components.navigation.page-nav.view
|
||||
quo2.components.navigation.top-nav.view
|
||||
quo2.components.notifications.activity-log.view
|
||||
quo2.components.notifications.activity-logs-photos.view
|
||||
quo2.components.notifications.count-down-circle
|
||||
|
@ -256,6 +257,7 @@
|
|||
;;;; Navigation
|
||||
(def floating-shell-button quo2.components.navigation.floating-shell-button.view/view)
|
||||
(def page-nav quo2.components.navigation.page-nav.view/page-nav)
|
||||
(def top-nav quo2.components.navigation.top-nav.view/view)
|
||||
|
||||
;;;; Markdown
|
||||
(def markdown-list quo2.components.markdown.list.view/view)
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
[quo2.components.loaders.skeleton-list.component-spec]
|
||||
[quo2.components.markdown.text-component-spec]
|
||||
[quo2.components.markdown.list.component-spec]
|
||||
[quo2.components.navigation.top-nav.component-spec]
|
||||
[quo2.components.notifications.notification.component-spec]
|
||||
[quo2.components.numbered-keyboard.keyboard-key.component-spec]
|
||||
[quo2.components.onboarding.small-option-card.component-spec]
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.common.home.banner.style :as style]
|
||||
[status-im2.common.home.view :as common.home]
|
||||
[status-im2.common.home.title-column.view :as title-column]
|
||||
[status-im2.common.home.top-nav.view :as top-nav]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def card-banner-overflow-threshold 3)
|
||||
|
@ -44,8 +45,8 @@
|
|||
[{:keys [title-props card-props scroll-shared-value]}]
|
||||
(let [customization-color (rf/sub [:profile/customization-color])]
|
||||
[reanimated/view {:style (style/banner-card-hiding-layer scroll-shared-value)}
|
||||
[common.home/top-nav {:type :grey}]
|
||||
[common.home/title-column (assoc title-props :customization-color customization-color)]
|
||||
[top-nav/view]
|
||||
[title-column/view (assoc title-props :customization-color customization-color)]
|
||||
[rn/view {:style {:overflow @card-banner-overflow}}
|
||||
[reanimated/view {:style (style/animated-banner-card scroll-shared-value)}
|
||||
[quo/discover-card card-props]]]]))
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
(ns status-im2.common.home.constants)
|
||||
|
||||
(def header-height 245)
|
|
@ -0,0 +1,10 @@
|
|||
(ns status-im2.common.home.empty-state.style
|
||||
(:require [react-native.safe-area :as safe-area]
|
||||
[status-im2.common.home.constants :as constants]))
|
||||
|
||||
(defn empty-state-container
|
||||
[]
|
||||
{:flex 1
|
||||
:margin-top (+ constants/header-height (safe-area/get-top))
|
||||
:margin-bottom 44
|
||||
:justify-content :center})
|
|
@ -0,0 +1,17 @@
|
|||
(ns status-im2.common.home.empty-state.view
|
||||
(:require
|
||||
[quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.home.empty-state.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [selected-tab tab->content]}]
|
||||
(let [{:keys [image title description]} (tab->content selected-tab)
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[rn/view {:style (style/empty-state-container)}
|
||||
[quo/empty-state
|
||||
{:customization-color customization-color
|
||||
:image image
|
||||
:title title
|
||||
:description description}]]))
|
|
@ -0,0 +1,7 @@
|
|||
(ns status-im2.common.home.header-spacing.style
|
||||
(:require [status-im2.common.home.constants :as constants]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(defn header-spacing
|
||||
[]
|
||||
{:height (+ constants/header-height (safe-area/get-top))})
|
|
@ -0,0 +1,7 @@
|
|||
(ns status-im2.common.home.header-spacing.view
|
||||
(:require [status-im2.common.home.header-spacing.style :as style]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
[rn/view {:style (style/header-spacing)}])
|
|
@ -1,60 +0,0 @@
|
|||
(ns status-im2.common.home.style
|
||||
(:require [react-native.safe-area :as safe-area]))
|
||||
|
||||
(def title-column
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:height 56
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 20
|
||||
:background-color :transparent})
|
||||
|
||||
(def title-column-text
|
||||
{:accessibility-label :communities-screen-title
|
||||
:margin-right 6
|
||||
:weight :semi-bold
|
||||
:size :heading-1})
|
||||
|
||||
(defn unread-indicator
|
||||
[unread-count max-value]
|
||||
(let [right-offset (cond
|
||||
(> unread-count max-value)
|
||||
-14
|
||||
|
||||
;; Greater than 9 means we'll need 2 digits to represent
|
||||
;; the text.
|
||||
(> unread-count 9)
|
||||
-10
|
||||
|
||||
:else -6)]
|
||||
{:position :absolute
|
||||
:top -6
|
||||
:right right-offset
|
||||
:z-index 4}))
|
||||
|
||||
(def left-section
|
||||
{:position :absolute
|
||||
:left 20
|
||||
:top 12})
|
||||
|
||||
(def right-section
|
||||
{:position :absolute
|
||||
:right 20
|
||||
:top 12
|
||||
:flex-direction :row})
|
||||
|
||||
(def top-nav-container
|
||||
{:height 56})
|
||||
|
||||
(def header-height 245)
|
||||
|
||||
(defn header-spacing
|
||||
[]
|
||||
{:height (+ header-height (safe-area/get-top))})
|
||||
|
||||
(defn empty-state-container
|
||||
[]
|
||||
{:flex 1
|
||||
:margin-top (+ header-height (safe-area/get-top))
|
||||
:margin-bottom 44
|
||||
:justify-content :center})
|
|
@ -0,0 +1,15 @@
|
|||
(ns status-im2.common.home.title-column.style)
|
||||
|
||||
(def title-column
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:height 56
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 20
|
||||
:background-color :transparent})
|
||||
|
||||
(def title-column-text
|
||||
{:accessibility-label :communities-screen-title
|
||||
:margin-right 6
|
||||
:weight :semi-bold
|
||||
:size :heading-1})
|
|
@ -0,0 +1,17 @@
|
|||
(ns status-im2.common.home.title-column.view
|
||||
(:require
|
||||
[quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.home.title-column.style :as style]
|
||||
[status-im2.common.plus-button.view :as plus-button]))
|
||||
|
||||
(defn view
|
||||
[{:keys [label handler accessibility-label customization-color]}]
|
||||
[rn/view style/title-column
|
||||
[rn/view {:flex 1}
|
||||
[quo/text style/title-column-text
|
||||
label]]
|
||||
[plus-button/plus-button
|
||||
{:on-press handler
|
||||
:accessibility-label accessibility-label
|
||||
:customization-color customization-color}]])
|
|
@ -0,0 +1,5 @@
|
|||
(ns status-im2.common.home.top-nav.style)
|
||||
|
||||
(def top-nav-container
|
||||
{:margin-left 20
|
||||
:margin-right 20})
|
|
@ -0,0 +1,62 @@
|
|||
(ns status-im2.common.home.top-nav.view
|
||||
(:require
|
||||
[quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im2.common.home.top-nav.style :as style]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.debounce :refer [dispatch-and-chill]]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn connectivity-sheet
|
||||
[]
|
||||
(let [peers-count (rf/sub [:peers-count])
|
||||
network-type (rf/sub [:network/type])]
|
||||
[rn/view
|
||||
[quo/text {:accessibility-label :peers-network-type-text} (str "NETWORK TYPE: " network-type)]
|
||||
[quo/text {:accessibility-label :peers-count-text} (str "PEERS COUNT: " peers-count)]]))
|
||||
|
||||
(defn view
|
||||
"[top-nav props]
|
||||
props
|
||||
{:blur? true/false
|
||||
:jump-to? true/false
|
||||
:container-style passed to outer view of component}"
|
||||
[{:keys [container-style blur? jump-to?]}]
|
||||
(let [{:keys [public-key]} (rf/sub [:profile/profile])
|
||||
online? (rf/sub [:visibility-status-updates/online? public-key])
|
||||
account (rf/sub [:profile/multiaccount])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
avatar {:online? online?
|
||||
:full-name (multiaccounts/displayed-name account)
|
||||
:profile-picture (multiaccounts/displayed-photo account)}
|
||||
network-type (rf/sub [:network/type])
|
||||
unread-count (rf/sub [:activity-center/unread-count])
|
||||
indicator (rf/sub [:activity-center/unread-indicator])
|
||||
notification-type (case indicator
|
||||
:unread-indicator/seen :mention-seen ; should be `seen` - TODO discuss
|
||||
; with design team about
|
||||
; notifications for activity centre
|
||||
:unread-indicator/new :mention ; should be :notification TODO
|
||||
; https://github.com/status-im/status-mobile/issues/17102
|
||||
nil)]
|
||||
[quo/top-nav
|
||||
{:avatar-on-press #(rf/dispatch [:navigate-to :my-profile])
|
||||
:scan-on-press #(js/alert "to be implemented")
|
||||
:activity-center-on-press #(rf/dispatch [:activity-center/open])
|
||||
:qr-code-on-press #(dispatch-and-chill [:open-modal :share-shell] 1000)
|
||||
:container-style (merge style/top-nav-container container-style)
|
||||
:blur? blur?
|
||||
:jump-to? jump-to?
|
||||
:customization-color customization-color
|
||||
:avatar-props avatar
|
||||
:max-unread-notifications constants/activity-center-max-unread-count
|
||||
:notification-count unread-count
|
||||
:notification notification-type
|
||||
:for-qa-only-cellular-network {:accessibility-label :on-cellular-network
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content connectivity-sheet}])}
|
||||
:for-qa-only-no-network {:accessibility-label :no-network-connection
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content connectivity-sheet}])}
|
||||
:for-qa-only-network-type network-type}]))
|
|
@ -1,145 +0,0 @@
|
|||
(ns status-im2.common.home.view
|
||||
(:require
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im2.common.home.style :as style]
|
||||
[status-im2.common.plus-button.view :as plus-button]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.debounce :refer [dispatch-and-chill]]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn title-column
|
||||
[{:keys [label handler accessibility-label customization-color]}]
|
||||
[rn/view style/title-column
|
||||
[rn/view {:flex 1}
|
||||
[quo/text style/title-column-text
|
||||
label]]
|
||||
[plus-button/plus-button
|
||||
{:on-press handler
|
||||
:accessibility-label accessibility-label
|
||||
:customization-color customization-color}]])
|
||||
|
||||
(defn- get-button-common-props
|
||||
[type background]
|
||||
(let [default? (= type :default)
|
||||
dark? (colors/dark?)]
|
||||
{:icon-only? true
|
||||
:size 32
|
||||
:container-style {:margin-left 12}
|
||||
:type (if default?
|
||||
(if dark? :grey :dark-grey)
|
||||
type)
|
||||
:background background}))
|
||||
|
||||
(defn- unread-indicator
|
||||
[]
|
||||
(let [unread-count (rf/sub [:activity-center/unread-count])
|
||||
indicator (rf/sub [:activity-center/unread-indicator])
|
||||
unread-type (case indicator
|
||||
:unread-indicator/seen :grey
|
||||
:unread-indicator/new :default
|
||||
nil)
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
(when (pos? unread-count)
|
||||
[quo/counter
|
||||
{:customization-color customization-color
|
||||
:accessibility-label :activity-center-unread-count
|
||||
:type unread-type
|
||||
:container-style (style/unread-indicator unread-count
|
||||
constants/activity-center-max-unread-count)}
|
||||
unread-count])))
|
||||
|
||||
(defn- left-section
|
||||
[{:keys [avatar]}]
|
||||
(let [{:keys [public-key]} (rf/sub [:profile/profile])
|
||||
online? (rf/sub [:visibility-status-updates/online? public-key])]
|
||||
[rn/touchable-without-feedback {:on-press #(rf/dispatch [:navigate-to :my-profile])}
|
||||
[rn/view
|
||||
{:accessibility-label :open-profile
|
||||
:style style/left-section}
|
||||
[quo/user-avatar
|
||||
(merge {:size :small :online? online?} avatar)]]]))
|
||||
|
||||
(defn connectivity-sheet
|
||||
[]
|
||||
(let [peers-count (rf/sub [:peers-count])
|
||||
network-type (rf/sub [:network/type])]
|
||||
[rn/view
|
||||
[quo/text {:accessibility-label :peers-network-type-text} (str "NETWORK TYPE: " network-type)]
|
||||
[quo/text {:accessibility-label :peers-count-text} (str "PEERS COUNT: " peers-count)]]))
|
||||
|
||||
(defn- right-section
|
||||
[{:keys [button-type search? button-background]}]
|
||||
(let [button-common-props (get-button-common-props button-type button-background)
|
||||
network-type (rf/sub [:network/type])]
|
||||
[rn/view {:style style/right-section}
|
||||
(when (= network-type "cellular")
|
||||
[quo/button
|
||||
(merge button-common-props
|
||||
{:accessibility-label :on-cellular-network
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content connectivity-sheet}])})
|
||||
"🦄"])
|
||||
(when (= network-type "none")
|
||||
[quo/button
|
||||
(merge button-common-props
|
||||
{:accessibility-label :no-network-connection
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content connectivity-sheet}])})
|
||||
"💀"])
|
||||
(when search?
|
||||
[quo/button
|
||||
(assoc button-common-props :accessibility-label :open-search-button)
|
||||
:i/search])
|
||||
[quo/button
|
||||
(assoc button-common-props :accessibility-label :open-scanner-button)
|
||||
:i/scan]
|
||||
[quo/button
|
||||
(merge button-common-props
|
||||
{:accessibility-label :show-qr-button
|
||||
:on-press #(dispatch-and-chill [:open-modal :share-shell] 1000)})
|
||||
:i/qr-code]
|
||||
[rn/view
|
||||
[quo/button
|
||||
(merge button-common-props
|
||||
{:accessibility-label :open-activity-center-button
|
||||
:on-press #(rf/dispatch [:activity-center/open])})
|
||||
:i/activity-center]
|
||||
[unread-indicator]]]))
|
||||
|
||||
;; TODO: should be moved to quo2 https://github.com/status-im/status-mobile/issues/16964
|
||||
(defn top-nav
|
||||
"[top-nav props]
|
||||
props
|
||||
{:type quo/button types
|
||||
:background quo/button background
|
||||
:style override-style
|
||||
:search? When non-nil, show search button}
|
||||
"
|
||||
[{:keys [type style search? background]
|
||||
:or {type :default}}]
|
||||
(let [account (rf/sub [:profile/multiaccount])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
avatar {:customization-color customization-color
|
||||
:full-name (multiaccounts/displayed-name account)
|
||||
:profile-picture (multiaccounts/displayed-photo account)}]
|
||||
[rn/view {:style (merge style/top-nav-container style)}
|
||||
[left-section {:avatar avatar}]
|
||||
[right-section {:button-type type :button-background background :search? search?}]]))
|
||||
|
||||
(defn header-spacing
|
||||
[]
|
||||
[rn/view {:style (style/header-spacing)}])
|
||||
|
||||
(defn empty-state-image
|
||||
[{:keys [selected-tab tab->content]}]
|
||||
(let [{:keys [image title description]} (tab->content selected-tab)
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[rn/view {:style (style/empty-state-container)}
|
||||
[quo/empty-state
|
||||
{:customization-color customization-color
|
||||
:image image
|
||||
:title title
|
||||
:description description}]]))
|
|
@ -50,32 +50,34 @@
|
|||
:no-notifications-dark (js/require "../resources/images/ui2/no-notifications-dark.png")})
|
||||
|
||||
(def mock-images
|
||||
{:diamond (js/require "../resources/images/mock2/diamond.png")
|
||||
:coinbase (js/require "../resources/images/mock2/coinbase.png")
|
||||
:collectible (js/require "../resources/images/mock2/collectible.png")
|
||||
:contact (js/require "../resources/images/mock2/contact.png")
|
||||
:community-banner (js/require "../resources/images/mock2/community-banner.png")
|
||||
:community-logo (js/require "../resources/images/mock2/community-logo.png")
|
||||
:community-cover (js/require "../resources/images/mock2/community-cover.png")
|
||||
:dark-blur-bg (js/require "../resources/images/mock2/dark_blur_bg.png")
|
||||
:decentraland (js/require "../resources/images/mock2/decentraland.png")
|
||||
:gif (js/require "../resources/images/mock2/gif.png")
|
||||
:monkey (js/require "../resources/images/mock2/monkey.png")
|
||||
:photo1 (js/require "../resources/images/mock2/photo1.png")
|
||||
:photo2 (js/require "../resources/images/mock2/photo2.png")
|
||||
:photo3 (js/require "../resources/images/mock2/photo3.png")
|
||||
:pinterest (js/require "../resources/images/mock2/pinterest.png")
|
||||
:qr-code (js/require "../resources/images/mock2/qr-code.png")
|
||||
:rarible (js/require "../resources/images/mock2/rarible.png")
|
||||
:small-opt-card-icon (js/require "../resources/images/mock2/small_opt_card_icon.png")
|
||||
:small-opt-card-main (js/require "../resources/images/mock2/small_opt_card_main.png")
|
||||
:status-logo (js/require "../resources/images/mock2/status-logo.png")
|
||||
:sticker (js/require "../resources/images/mock2/sticker.png")
|
||||
:ring (js/require "../resources/images/mock2/ring.png")
|
||||
:verified (js/require "../resources/images/mock2/verified.png")
|
||||
:user-picture-female2 (js/require "../resources/images/mock2/user_picture_female2.png")
|
||||
:user-picture-male4 (js/require "../resources/images/mock2/user_picture_male4.png")
|
||||
:user-picture-male5 (js/require "../resources/images/mock2/user_picture_male5.png")})
|
||||
{:diamond (js/require "../resources/images/mock2/diamond.png")
|
||||
:coinbase (js/require "../resources/images/mock2/coinbase.png")
|
||||
:collectible (js/require "../resources/images/mock2/collectible.png")
|
||||
:contact (js/require "../resources/images/mock2/contact.png")
|
||||
:community-banner (js/require "../resources/images/mock2/community-banner.png")
|
||||
:community-logo (js/require "../resources/images/mock2/community-logo.png")
|
||||
:community-cover (js/require "../resources/images/mock2/community-cover.png")
|
||||
:dark-blur-bg (js/require "../resources/images/mock2/dark_blur_bg.png")
|
||||
:dark-blur-background (js/require "../resources/images/mock2/dark-blur-background.png")
|
||||
:decentraland (js/require "../resources/images/mock2/decentraland.png")
|
||||
:gif (js/require "../resources/images/mock2/gif.png")
|
||||
:monkey (js/require "../resources/images/mock2/monkey.png")
|
||||
:light-blur-background (js/require "../resources/images/mock2/light-blur-background.png")
|
||||
:photo1 (js/require "../resources/images/mock2/photo1.png")
|
||||
:photo2 (js/require "../resources/images/mock2/photo2.png")
|
||||
:photo3 (js/require "../resources/images/mock2/photo3.png")
|
||||
:pinterest (js/require "../resources/images/mock2/pinterest.png")
|
||||
:qr-code (js/require "../resources/images/mock2/qr-code.png")
|
||||
:rarible (js/require "../resources/images/mock2/rarible.png")
|
||||
:small-opt-card-icon (js/require "../resources/images/mock2/small_opt_card_icon.png")
|
||||
:small-opt-card-main (js/require "../resources/images/mock2/small_opt_card_main.png")
|
||||
:status-logo (js/require "../resources/images/mock2/status-logo.png")
|
||||
:sticker (js/require "../resources/images/mock2/sticker.png")
|
||||
:ring (js/require "../resources/images/mock2/ring.png")
|
||||
:verified (js/require "../resources/images/mock2/verified.png")
|
||||
:user-picture-female2 (js/require "../resources/images/mock2/user_picture_female2.png")
|
||||
:user-picture-male4 (js/require "../resources/images/mock2/user_picture_male4.png")
|
||||
:user-picture-male5 (js/require "../resources/images/mock2/user_picture_male5.png")})
|
||||
|
||||
(def parallax-video
|
||||
{:biometrics [(js/require "../resources/videos2/biometrics_01.mp4")
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
||||
[status-im2.common.contact-list.view :as contact-list]
|
||||
[status-im2.common.home.actions.view :as actions]
|
||||
[status-im2.common.home.banner.view :as common.home.banner]
|
||||
[status-im2.common.home.view :as common.home]
|
||||
[status-im2.common.home.banner.view :as common.banner]
|
||||
[status-im2.common.home.empty-state.view :as common.empty-state]
|
||||
[status-im2.common.home.header-spacing.view :as common.header-spacing]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.chat.actions.view :as chat.actions.view]
|
||||
[status-im2.contexts.chat.home.chat-list-item.view :as chat-list-item]
|
||||
|
@ -50,21 +51,21 @@
|
|||
(let [unfiltered-items (rf/sub [:chats-stack-items])
|
||||
items (filter-and-sort-items-by-tab selected-tab unfiltered-items)]
|
||||
(if (empty? items)
|
||||
[common.home/empty-state-image
|
||||
[common.empty-state/view
|
||||
{:selected-tab selected-tab
|
||||
:tab->content (empty-state-content theme)}]
|
||||
[reanimated/flat-list
|
||||
{:ref set-scroll-ref
|
||||
:key-fn #(or (:chat-id %) (:public-key %) (:id %))
|
||||
:content-inset-adjustment-behavior :never
|
||||
:header [common.home/header-spacing]
|
||||
:header [common.header-spacing/view]
|
||||
:get-item-layout get-item-layout
|
||||
:on-end-reached #(re-frame/dispatch [:chat/show-more-chats])
|
||||
:keyboard-should-persist-taps :always
|
||||
:data items
|
||||
:render-fn chat-list-item/chat-list-item
|
||||
:scroll-event-throttle 8
|
||||
:on-scroll #(common.home.banner/set-scroll-shared-value
|
||||
:on-scroll #(common.banner/set-scroll-shared-value
|
||||
{:scroll-input (oops/oget % "nativeEvent.contentOffset.y")
|
||||
:shared-value scroll-shared-value})}])))
|
||||
|
||||
|
@ -85,7 +86,7 @@
|
|||
[{:keys [theme pending-contact-requests set-scroll-ref scroll-shared-value]}]
|
||||
(let [items (rf/sub [:contacts/active-sections])]
|
||||
(if (and (empty? items) (empty? pending-contact-requests))
|
||||
[common.home/empty-state-image
|
||||
[common.empty-state/view
|
||||
{:selected-tab :tab/contacts
|
||||
:tab->content (empty-state-content theme)}]
|
||||
[rn/section-list
|
||||
|
@ -94,7 +95,7 @@
|
|||
:get-item-layout get-item-layout
|
||||
:content-inset-adjustment-behavior :never
|
||||
:header [:<>
|
||||
[common.home/header-spacing]
|
||||
[common.header-spacing/view]
|
||||
(when (seq pending-contact-requests)
|
||||
[contact-request/contact-requests
|
||||
pending-contact-requests])]
|
||||
|
@ -103,7 +104,7 @@
|
|||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:render-fn contact-item-render
|
||||
:scroll-event-throttle 8
|
||||
:on-scroll #(common.home.banner/set-scroll-shared-value
|
||||
:on-scroll #(common.banner/set-scroll-shared-value
|
||||
{:scroll-input (oops/oget % "nativeEvent.contentOffset.y")
|
||||
:shared-value scroll-shared-value})}])))
|
||||
|
||||
|
@ -139,7 +140,7 @@
|
|||
:set-scroll-ref set-scroll-ref
|
||||
:scroll-shared-value scroll-shared-value
|
||||
:theme theme}])
|
||||
[:f> common.home.banner/animated-banner
|
||||
[:f> common.banner/animated-banner
|
||||
{:content banner-data
|
||||
:customization-color customization-color
|
||||
:scroll-ref scroll-ref
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.common.home.banner.view :as common.home.banner]
|
||||
[status-im2.common.home.view :as common.home]
|
||||
[status-im2.common.home.banner.view :as common.banner]
|
||||
[status-im2.common.home.empty-state.view :as common.empty-state]
|
||||
[status-im2.common.home.header-spacing.view :as common.header-spacing]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.communities.actions.community-options.view :as options]
|
||||
[status-im2.contexts.communities.actions.home-plus.view :as actions.home-plus]
|
||||
|
@ -90,24 +91,24 @@
|
|||
scroll-shared-value (reanimated/use-shared-value 0)]
|
||||
[:<>
|
||||
(if (empty? selected-items)
|
||||
[common.home/empty-state-image
|
||||
[common.empty-state/view
|
||||
{:selected-tab selected-tab
|
||||
:tab->content (empty-state-content theme)}]
|
||||
[reanimated/flat-list
|
||||
{:ref set-flat-list-ref
|
||||
:key-fn :id
|
||||
:content-inset-adjustment-behavior :never
|
||||
:header [common.home/header-spacing]
|
||||
:header [common.header-spacing/view]
|
||||
:render-fn item-render
|
||||
:style {:margin-top -1}
|
||||
:data selected-items
|
||||
:scroll-event-throttle 8
|
||||
:on-scroll #(common.home.banner/set-scroll-shared-value
|
||||
:on-scroll #(common.banner/set-scroll-shared-value
|
||||
{:scroll-input (oops/oget
|
||||
%
|
||||
"nativeEvent.contentOffset.y")
|
||||
:shared-value scroll-shared-value})}])
|
||||
[:f> common.home.banner/animated-banner
|
||||
[:f> common.banner/animated-banner
|
||||
{:content banner-data
|
||||
:customization-color customization-color
|
||||
:scroll-ref flat-list-ref
|
||||
|
|
|
@ -280,7 +280,7 @@
|
|||
:navigation [{:name :bottom-nav-tab
|
||||
:component bottom-nav-tab/preview-bottom-nav-tab}
|
||||
{:name :top-nav
|
||||
:component top-nav/preview-top-nav}
|
||||
:component top-nav/preview}
|
||||
{:name :page-nav
|
||||
:component page-nav/preview-page-nav}
|
||||
{:name :floating-shell-button
|
||||
|
|
|
@ -2,56 +2,75 @@
|
|||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.home.view :as home.view]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
[quo2.core :as quo]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]
|
||||
[status-im2.common.resources :as resources]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Type"
|
||||
:key :type
|
||||
[{:key :notification
|
||||
:type :select
|
||||
:options [{:key :default
|
||||
:value "Default"}
|
||||
{:key :blur-bg
|
||||
:value "Blurred BG"}
|
||||
{:key :black
|
||||
:value "Black"}]}
|
||||
{:label "New Notifications?"
|
||||
:key :new-notifications?
|
||||
:type :boolean}
|
||||
{:label "Notification Indicator"
|
||||
:key :notification-indicator
|
||||
:type :select
|
||||
:options [{:key :unread-dot
|
||||
:value :unread-dot}
|
||||
{:key :counter
|
||||
:value :counter}]}
|
||||
{:label "Counter Label"
|
||||
:key :counter-label
|
||||
:type :text}])
|
||||
:options [{:key :mention
|
||||
:value "Mention"}
|
||||
{:key :notification
|
||||
:value "Notification"}
|
||||
{:key :seen
|
||||
:value "Seen"}]}
|
||||
{:key :blur?
|
||||
:type :boolean}
|
||||
{:key :jump-to?
|
||||
:type :boolean}
|
||||
{:key :notification-count
|
||||
:type :number}
|
||||
(preview/customization-color-option)])
|
||||
|
||||
(defn cool-preview
|
||||
(defn preview
|
||||
[]
|
||||
(let [state (reagent/atom {:type :default
|
||||
:new-notifications? true
|
||||
:notification-indicator :unread-dot
|
||||
:counter-label 5})]
|
||||
(let [state (reagent/atom {:noticication-count 0
|
||||
:customization-color :blue})]
|
||||
(fn []
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view {:padding-bottom 150}
|
||||
[preview/customizer state descriptor]
|
||||
[rn/view
|
||||
{:padding-vertical 60
|
||||
:flex-direction :row
|
||||
:align-items :center}
|
||||
[home.view/top-nav @state (:value @state)]]]])))
|
||||
(let [blur? (:blur? @state)
|
||||
customization-color (:customization-color @state)
|
||||
jump-to? (:jump-to? @state)
|
||||
notification (:notification @state)
|
||||
notification-count (:notification-count @state)]
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view {:padding-bottom 150}
|
||||
[preview/customizer state descriptor]
|
||||
[rn/view
|
||||
{:padding-vertical 60
|
||||
:padding-horizontal 20
|
||||
:flex-direction :row
|
||||
:align-items :center}
|
||||
(when blur?
|
||||
[rn/image
|
||||
{:source (resources/get-mock-image (quo.theme/theme-value :light-blur-background
|
||||
:dark-blur-background))
|
||||
:style {:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0}}])
|
||||
(when jump-to?
|
||||
[rn/image
|
||||
{:background-color colors/neutral-100
|
||||
:style {:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0}}])
|
||||
[quo/top-nav
|
||||
{:container-style {:flex 1 :z-index 2}
|
||||
:max-unread-notifications 99
|
||||
:blur? blur?
|
||||
:notification notification
|
||||
:customization-color customization-color
|
||||
:notification-count notification-count
|
||||
:jump-to? jump-to?
|
||||
:avatar-props {:online? true
|
||||
:full-name "Test User"}
|
||||
:avatar-on-press #(js/alert "avatar pressed")
|
||||
:scan-on-press #(js/alert "scan pressed")
|
||||
:activity-center-on-press #(js/alert "activity-center pressed")
|
||||
:qr-code-on-press #(js/alert "qr pressed")}]]]]))))
|
||||
|
||||
(defn preview-top-nav
|
||||
[]
|
||||
[rn/view
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-95)
|
||||
:flex 1}
|
||||
[rn/flat-list
|
||||
{:flex 1
|
||||
:keyboard-should-persist-taps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
[react-native.safe-area :as safe-area]
|
||||
[status-im2.contexts.shell.jump-to.state :as state]
|
||||
[status-im2.contexts.shell.jump-to.utils :as utils]
|
||||
[status-im2.common.home.view :as common.home]
|
||||
[status-im2.common.home.top-nav.view :as common.top-nav]
|
||||
[status-im2.contexts.shell.jump-to.constants :as shell.constants]
|
||||
[status-im2.contexts.shell.jump-to.components.jump-to-screen.style :as style]
|
||||
[status-im2.contexts.shell.jump-to.components.bottom-tabs.view :as bottom-tabs]
|
||||
|
@ -109,7 +109,7 @@
|
|||
:background-color colors/neutral-100}}
|
||||
[jump-to-list switcher-cards shell-margin]
|
||||
[top-nav-blur-overlay top]
|
||||
[common.home/top-nav
|
||||
{:type :black
|
||||
:style {:margin-top top
|
||||
:z-index 2}}]]]))
|
||||
[common.top-nav/view
|
||||
{:jump-to? true
|
||||
:container-style {:margin-top top
|
||||
:z-index 2}}]]]))
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
[quo2.core :as quo]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.home.view :as common.home]
|
||||
[status-im2.common.home.top-nav.view :as common.top-nav]
|
||||
[status-im2.contexts.wallet.home.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
|
@ -50,7 +50,7 @@
|
|||
[rn/view
|
||||
{:style {:margin-top top
|
||||
:flex 1}}
|
||||
[common.home/top-nav {:type :grey}]
|
||||
[common.top-nav/view]
|
||||
[quo/wallet-overview temp/wallet-overview-state]
|
||||
[rn/pressable
|
||||
{:on-long-press #(rf/dispatch [:show-bottom-sheet {:content temp/wallet-temporary-navigation}])}
|
||||
|
|
Loading…
Reference in New Issue