showing sticky bar on scrolling discover screen (#14825)
This commit is contained in:
parent
89039cd79a
commit
91d0e106f2
|
@ -210,8 +210,8 @@ PODS:
|
|||
- React
|
||||
- react-native-blob-util (0.13.18):
|
||||
- React-Core
|
||||
- react-native-blur (3.6.1):
|
||||
- React
|
||||
- react-native-blur (4.3.0):
|
||||
- React-Core
|
||||
- react-native-camera-kit (8.0.4):
|
||||
- React
|
||||
- react-native-cameraroll (4.0.4):
|
||||
|
@ -640,7 +640,7 @@ SPEC CHECKSUMS:
|
|||
FBLazyVector: 352a8ca9bbc8e2f097d680747a8c97ecef12d469
|
||||
FBReactNativeSpec: 7dfb84f624136a45727c813ed21d130cd3e61beb
|
||||
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
||||
glog: 6934faae5afbec23475648c8aeb6047ce973af65
|
||||
glog: 997518ea2aa2d8cd5df9797b641b758d52ecf2bc
|
||||
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
||||
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
|
||||
libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c
|
||||
|
@ -658,7 +658,7 @@ SPEC CHECKSUMS:
|
|||
React-jsinspector: fdbc08866b34ae8e1b788ea1cbd9f9d1ca2aa3d6
|
||||
react-native-background-timer: 1f7d560647b40e6a60b01c452ba29c54bf581fc4
|
||||
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
|
||||
react-native-blur: 4568dd93d1d82748c180df8beb2d929c97b13b47
|
||||
react-native-blur: 50c9feabacbc5f49b61337ebc32192c6be7ec3c3
|
||||
react-native-camera-kit: 498a6d111a904834e0824e9073cfadef7303235f
|
||||
react-native-cameraroll: 88f4e62d9ecd0e1f253abe4f685474f2ea14bfa2
|
||||
react-native-config: c98128a72bc2c3a1ca72caec0b021f0fa944aa29
|
||||
|
|
|
@ -255,7 +255,8 @@
|
|||
{:background-color
|
||||
(if (= state :pressed)
|
||||
(colors/theme-colors colors/neutral-100 colors/white)
|
||||
:transparent)}
|
||||
:transparent)
|
||||
:width width}
|
||||
style)}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
(defn community-card-view-item
|
||||
[{:keys [name description locked images
|
||||
status tokens cover tags width]} on-press]
|
||||
[rn/touchable-opacity
|
||||
[rn/touchable-without-feedback
|
||||
{:accessibility-label :community-card-item
|
||||
:on-press on-press}
|
||||
[rn/view {:style (style/community-card 20)}
|
||||
|
|
|
@ -12,23 +12,30 @@
|
|||
:flex 1})
|
||||
|
||||
(defn blur-slider
|
||||
[animation]
|
||||
[animation height]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY animation}]}
|
||||
{:z-index 5
|
||||
:top 0
|
||||
:position :absolute
|
||||
:height (if platform/ios? 100 124)
|
||||
:width "100%"
|
||||
:flex 1}))
|
||||
:top 0
|
||||
:height height
|
||||
:right 0
|
||||
:left 0
|
||||
:background-color (if platform/ios?
|
||||
(colors/theme-colors
|
||||
colors/white-opa-70
|
||||
colors/neutral-95-opa-70)
|
||||
:transparent)}))
|
||||
|
||||
(defn scroll-view-container
|
||||
[border-radius]
|
||||
{:position :absolute
|
||||
{:flex 1
|
||||
:position :absolute
|
||||
:top -48
|
||||
:left 0
|
||||
:right 0
|
||||
:overflow :scroll
|
||||
:border-radius border-radius
|
||||
:height "100%"})
|
||||
:border-radius border-radius})
|
||||
|
||||
(defn sticky-header-title
|
||||
[animation]
|
||||
|
|
|
@ -27,9 +27,17 @@
|
|||
(min maximum)))
|
||||
|
||||
(defn scroll-page-header
|
||||
[scroll-height name page-nav cover sticky-header]
|
||||
[scroll-height
|
||||
height
|
||||
name
|
||||
page-nav
|
||||
cover
|
||||
sticky-header
|
||||
top-nav
|
||||
title-colum
|
||||
navigate-back?]
|
||||
(let [input-range (if platform/ios? [-47 10] [0 150])
|
||||
output-range (if platform/ios? [-100 0] [-169 -45])
|
||||
output-range (if platform/ios? [-208 0] [-208 -45])
|
||||
y (reanimated/use-shared-value scroll-height)
|
||||
translate-animation (reanimated/interpolate y
|
||||
input-range
|
||||
|
@ -47,13 +55,14 @@
|
|||
[scroll-height])
|
||||
[:<>
|
||||
[reanimated/blur-view
|
||||
{:blur-amount 32
|
||||
:blur-type :xlight
|
||||
:overlay-color (if platform/ios? colors/white-opa-70 :transparent)
|
||||
:style (style/blur-slider translate-animation)}]
|
||||
{:blur-amount 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent
|
||||
:style (style/blur-slider translate-animation height)}]
|
||||
[rn/view
|
||||
{:style {:z-index 6
|
||||
:margin-top (if platform/ios? 44 0)}}
|
||||
(when cover
|
||||
[reanimated/view
|
||||
{:style (style/sticky-header-title opacity-animation)}
|
||||
[rn/image
|
||||
|
@ -63,19 +72,24 @@
|
|||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style {:line-height 21}}
|
||||
name]]
|
||||
name]])
|
||||
(if top-nav
|
||||
[top-nav]
|
||||
[quo/page-nav
|
||||
{:horizontal-description? true
|
||||
(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 page-nav
|
||||
:left-section {:icon :i/close
|
||||
:right-section-buttons page-nav}
|
||||
(when navigate-back?
|
||||
{:left-section {:icon :i/close
|
||||
:icon-background-color (icon-color)
|
||||
:on-press #(rf/dispatch [:navigate-back])}}]
|
||||
:on-press #(rf/dispatch [:navigate-back])}}))])
|
||||
(when title-colum
|
||||
[title-colum])
|
||||
sticky-header]]))
|
||||
|
||||
|
||||
|
@ -101,14 +115,24 @@
|
|||
(defn scroll-page
|
||||
[_ _ _]
|
||||
(let [scroll-height (reagent/atom negative-scroll-position-0)]
|
||||
(fn [{:keys [cover-image page-nav-right-section-buttons name on-scroll]}
|
||||
(fn
|
||||
[{:keys [cover-image
|
||||
page-nav-right-section-buttons
|
||||
name
|
||||
on-scroll
|
||||
height
|
||||
top-nav
|
||||
title-colum
|
||||
background-color
|
||||
navigate-back?]}
|
||||
sticky-header
|
||||
children]
|
||||
[:<>
|
||||
[:f> scroll-page-header @scroll-height name page-nav-right-section-buttons cover-image
|
||||
sticky-header]
|
||||
[:f> scroll-page-header @scroll-height height name
|
||||
page-nav-right-section-buttons cover-image sticky-header top-nav title-colum
|
||||
navigate-back?]
|
||||
[rn/scroll-view
|
||||
{:style (style/scroll-view-container
|
||||
{:content-container-style (style/scroll-view-container
|
||||
(diff-with-max-min @scroll-height 16 0))
|
||||
:shows-vertical-scroll-indicator false
|
||||
:scroll-event-throttle 16
|
||||
|
@ -119,17 +143,18 @@
|
|||
"nativeEvent.contentOffset.y")))
|
||||
(when on-scroll
|
||||
(on-scroll @scroll-height)))}
|
||||
(when cover-image
|
||||
[rn/view {:style {:height 151}}
|
||||
[rn/image
|
||||
{:source cover-image
|
||||
:style {:overflow :visible
|
||||
:flex 1}}]]
|
||||
:flex 1}}]])
|
||||
(when children
|
||||
[rn/view
|
||||
{:flex 1
|
||||
:border-radius (diff-with-max-min @scroll-height 16 0)
|
||||
:background-color (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-90)}
|
||||
[:f> display-picture @scroll-height cover-image]
|
||||
:background-color background-color
|
||||
:padding-top 48}
|
||||
(when cover-image
|
||||
[:f> display-picture @scroll-height cover-image])
|
||||
children])]])))
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
(ns status-im2.contexts.communities.discover.style
|
||||
(:require [react-native.platform :as platform]))
|
||||
|
||||
(def screen-title-container
|
||||
{:height 56
|
||||
:padding-vertical 12
|
||||
:justify-content :center})
|
||||
|
||||
(def featured-communities-header
|
||||
{:flex-direction :row
|
||||
:height 30
|
||||
:padding-top 8
|
||||
:margin-bottom 8
|
||||
:padding-right 20
|
||||
:justify-content :space-between})
|
||||
|
||||
(def featured-communities-title-container
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def featured-list-container
|
||||
{:flex-direction :row
|
||||
:overflow :hidden
|
||||
:margin-bottom 24})
|
||||
|
||||
(defn discover-communities-segments
|
||||
[fixed?]
|
||||
(merge
|
||||
{:padding-vertical 12
|
||||
:height 56
|
||||
:background-color :transparent}
|
||||
(when-not fixed?
|
||||
{:margin-top 12
|
||||
:margin-bottom 4})))
|
||||
|
||||
(defn discover-screen-container
|
||||
[background-color]
|
||||
{:background-color background-color
|
||||
:position :absolute
|
||||
:top (if platform/ios? 0 44)
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(defn blur-tabs-header
|
||||
[]
|
||||
{:padding-horizontal 20
|
||||
:position :absolute
|
||||
:top (if platform/ios? 56 60)
|
||||
:height 56
|
||||
:right 0
|
||||
:left 0
|
||||
:justify-content :center
|
||||
:flex 1
|
||||
:background-color :transparent})
|
|
@ -4,10 +4,14 @@
|
|||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im2.contexts.communities.menus.community-options.view :as options]
|
||||
[status-im.ui.screens.communities.community :as community]
|
||||
[status-im.ui.components.react :as react]
|
||||
[react-native.platform :as platform]
|
||||
[status-im2.common.scroll-page.view :as scroll-page]
|
||||
[status-im2.contexts.communities.discover.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def mock-community-item-data ;; TODO: remove once communities are loaded with this data.
|
||||
|
@ -29,10 +33,9 @@
|
|||
:resource (resources/get-image :podcasts)}]}})
|
||||
|
||||
(defn render-fn
|
||||
[community-item _ _ {:keys [featured? width view-type]}]
|
||||
[community-item _ _ {:keys [width view-type]}]
|
||||
(let [item (merge community-item
|
||||
(get mock-community-item-data :data)
|
||||
{:featured featured?})]
|
||||
(get mock-community-item-data :data))]
|
||||
(if (= view-type :card-view)
|
||||
[quo/community-card-view-item (assoc item :width width)
|
||||
#(rf/dispatch [:navigate-to :community-overview (:id item)])]
|
||||
|
@ -49,8 +52,7 @@
|
|||
(defn screen-title
|
||||
[]
|
||||
[rn/view
|
||||
{:height 56
|
||||
:padding-vertical 12}
|
||||
{:style style/screen-title-container}
|
||||
[quo/text
|
||||
{:accessibility-label :communities-screen-title
|
||||
:weight :semi-bold
|
||||
|
@ -60,13 +62,9 @@
|
|||
(defn featured-communities-header
|
||||
[communities-count]
|
||||
[rn/view
|
||||
{:flex-direction :row
|
||||
:height 30
|
||||
:margin-bottom 8
|
||||
:justify-content :space-between}
|
||||
{:style style/featured-communities-header}
|
||||
[rn/view
|
||||
{:flex-direction :row
|
||||
:align-items :center}
|
||||
{:style style/featured-communities-title-container}
|
||||
[quo/text
|
||||
{:accessibility-label :featured-communities-title
|
||||
:weight :semi-bold
|
||||
|
@ -83,18 +81,34 @@
|
|||
colors/neutral-50
|
||||
colors/neutral-40)}]])
|
||||
|
||||
(defn discover-communities-segments
|
||||
[selected-tab fixed]
|
||||
[rn/view
|
||||
{:style (style/discover-communities-segments fixed)}
|
||||
[quo/tabs
|
||||
{:size 32
|
||||
:on-change #(reset! selected-tab %)
|
||||
:default-active :all
|
||||
:data [{:id :all
|
||||
:label (i18n/label :t/all)
|
||||
:accessibility-label :all-communities-tab}
|
||||
{:id :open
|
||||
:label (i18n/label :t/open)
|
||||
:accessibility-label :open-communities-tab}
|
||||
{:id :gated
|
||||
:label (i18n/label :t/gated)
|
||||
:accessibility-label :gated-communities-tab}]}]])
|
||||
|
||||
|
||||
(defn featured-list
|
||||
[communities view-type]
|
||||
(let [view-size (reagent/atom 0)]
|
||||
(fn []
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:overflow :hidden
|
||||
:width "100%"
|
||||
:margin-bottom 24}
|
||||
{:style style/featured-list-container
|
||||
:on-layout #(swap! view-size
|
||||
(fn []
|
||||
(oops/oget % "nativeEvent.layout.width")))}
|
||||
(- (oops/oget % "nativeEvent.layout.width") 20)))}
|
||||
(when-not (= @view-size 0)
|
||||
[rn/flat-list
|
||||
{:key-fn :id
|
||||
|
@ -104,47 +118,134 @@
|
|||
:separator [rn/view {:width 12}]
|
||||
:data communities
|
||||
:render-fn render-fn
|
||||
:render-data {:featured? true
|
||||
:width @view-size
|
||||
:render-data {:width @view-size
|
||||
:view-type view-type}}])])))
|
||||
|
||||
(defn discover-communities-header
|
||||
[{:keys [featured-communities-count
|
||||
featured-communities
|
||||
view-type
|
||||
selected-tab]}]
|
||||
[react/animated-view
|
||||
[screen-title]
|
||||
[featured-communities-header featured-communities-count]
|
||||
[featured-list featured-communities view-type]
|
||||
[quo/separator]
|
||||
[discover-communities-segments selected-tab false]])
|
||||
|
||||
(defn other-communities-list
|
||||
[communities view-type]
|
||||
[rn/flat-list
|
||||
{:key-fn :id
|
||||
:keyboard-should-persist-taps :always
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:separator [rn/view {:margin-bottom 16}]
|
||||
:data communities
|
||||
:render-fn render-fn
|
||||
:render-data {:featured? false
|
||||
:width "100%"
|
||||
:view-type view-type}}])
|
||||
[{:keys [communities communities-ids view-type]}]
|
||||
[rn/view {:flex 1}
|
||||
(map-indexed
|
||||
(fn [inner-index item]
|
||||
(let [community-id (when communities-ids item)
|
||||
community (if communities
|
||||
item
|
||||
[rf/sub [:communities/home-item community-id]])]
|
||||
[rn/view
|
||||
{:key (str inner-index (:id community))
|
||||
:margin-bottom 16}
|
||||
(if (= view-type :card-view)
|
||||
[quo/community-card-view-item
|
||||
(merge community
|
||||
(get mock-community-item-data :data))
|
||||
#(rf/dispatch [:navigate-to :community-overview (:id community)])]
|
||||
[quo/communities-list-view-item
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:communities/load-category-states (:id community)])
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:navigate-to :community (:id community)]))
|
||||
:on-long-press #(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
;; TODO implement with quo2
|
||||
[community/community-actions community])}])}
|
||||
(merge community
|
||||
(get mock-community-item-data :data))])]))
|
||||
(if communities communities communities-ids))])
|
||||
|
||||
|
||||
(defn communities-lists
|
||||
[selected-tab view-type]
|
||||
(let [ids-by-user-involvement (rf/sub [:communities/community-ids-by-user-involvement])
|
||||
all-communities (rf/sub [:communities/sorted-communities])
|
||||
tab @selected-tab]
|
||||
[rn/view {:style {:flex 1}}
|
||||
(case tab
|
||||
:all
|
||||
(other-communities-list {:communities all-communities
|
||||
:view-type view-type})
|
||||
|
||||
:open
|
||||
(other-communities-list {:communities-ids (:open ids-by-user-involvement)
|
||||
:view-type view-type})
|
||||
|
||||
:gated
|
||||
(other-communities-list {:communities-ids (:gated ids-by-user-involvement)
|
||||
:view-type view-type})
|
||||
|
||||
[quo/information-box
|
||||
{:type :error
|
||||
:icon :i/info}
|
||||
(i18n/label :t/error)])]))
|
||||
|
||||
|
||||
(defn render-communities
|
||||
[selected-tab
|
||||
featured-communities-count
|
||||
featured-communities
|
||||
view-type]
|
||||
(fn []
|
||||
[rn/view {:padding-horizontal 20}
|
||||
[discover-communities-header
|
||||
{:selected-tab selected-tab
|
||||
:view-type view-type
|
||||
:featured-communities-count featured-communities-count
|
||||
:featured-communities featured-communities}]
|
||||
[communities-lists selected-tab view-type]]))
|
||||
|
||||
(defn render-sticky-header
|
||||
[{:keys [selected-tab scroll-height]}]
|
||||
(fn []
|
||||
(when (> @scroll-height 360)
|
||||
[rn/view
|
||||
{:style (style/blur-tabs-header)}
|
||||
[discover-communities-segments selected-tab true]])))
|
||||
|
||||
(defn discover-screen-content
|
||||
[featured-communities]
|
||||
(let [view-type (reagent/atom :card-view)
|
||||
selected-tab (reagent/atom :all)
|
||||
scroll-height (reagent/atom 0)
|
||||
featured-communities-count (count featured-communities)]
|
||||
(fn []
|
||||
[scroll-page/scroll-page
|
||||
{:name (i18n/label :t/discover-communities)
|
||||
:on-scroll #(reset! scroll-height %)
|
||||
:background-color (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-95)
|
||||
:navigate-back? :true
|
||||
:height (if platform/ios?
|
||||
(if (> @scroll-height 360)
|
||||
156
|
||||
100)
|
||||
(if (> @scroll-height 360)
|
||||
162
|
||||
106))}
|
||||
[render-sticky-header
|
||||
{:selected-tab selected-tab
|
||||
:scroll-height scroll-height}]
|
||||
[render-communities
|
||||
selected-tab
|
||||
featured-communities-count
|
||||
featured-communities
|
||||
@view-type]])))
|
||||
|
||||
(defn discover
|
||||
[]
|
||||
(let [view-type (reagent/atom :card-view)]
|
||||
(fn []
|
||||
(let [communities (rf/sub [:communities/sorted-communities])
|
||||
featured-communities (rf/sub [:communities/featured-communities])
|
||||
featured-communities-count (count featured-communities)]
|
||||
[safe-area/consumer
|
||||
(fn []
|
||||
(let [featured-communities (rf/sub [:communities/featured-communities])]
|
||||
[rn/view
|
||||
{:style {:margin-left 20
|
||||
:margin-right 20
|
||||
:flex 1
|
||||
:background-color (colors/theme-colors
|
||||
{:style (style/discover-screen-container (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-90)}}
|
||||
[quo/button
|
||||
{:icon true
|
||||
:type :grey
|
||||
:size 32
|
||||
:style {:margin-vertical 12}
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
:i/close]
|
||||
[screen-title]
|
||||
[featured-communities-header featured-communities-count]
|
||||
[featured-list featured-communities @view-type]
|
||||
[other-communities-list communities @view-type]])]))))
|
||||
colors/neutral-95))}
|
||||
[discover-screen-content featured-communities]]))
|
|
@ -56,7 +56,8 @@
|
|||
(let [ids-by-user-involvement (rf/sub [:communities/community-ids-by-user-involvement])
|
||||
tab @selected-tab]
|
||||
[rn/view
|
||||
{:style {:padding-horizontal 20
|
||||
{:style {:flex 1
|
||||
:padding-horizontal 20
|
||||
:padding-vertical 12}}
|
||||
(case tab
|
||||
:joined
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
{:position :absolute
|
||||
:top (if platform/ios? 56 60)
|
||||
:height 34
|
||||
:width "100%"
|
||||
:flex 1})
|
||||
:right 0
|
||||
:left 0
|
||||
:flex 1
|
||||
:background-color :transparent})
|
||||
|
||||
(def join-button
|
||||
{:width "100%"
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.constants :as constants]
|
||||
|
@ -262,11 +261,8 @@
|
|||
[_]
|
||||
(fn [{:keys [:enabled :label]}]
|
||||
(when enabled
|
||||
[blur/view
|
||||
{:blur-amount 32
|
||||
:blur-type :xlight
|
||||
:overlay-color (if platform/ios? colors/white-opa-70 :transparent)
|
||||
:style style/blur-channel-header}
|
||||
[rn/view
|
||||
{:style style/blur-channel-header}
|
||||
[quo/divider-label
|
||||
{:label (:label label)
|
||||
:chevron-position :left}]])))
|
||||
|
@ -293,7 +289,18 @@
|
|||
{:cover-image cover
|
||||
:page-nav-right-section-buttons (page-nav-right-section-buttons id)
|
||||
:name name
|
||||
:on-scroll #(reset! scroll-height %)}
|
||||
:on-scroll #(reset! scroll-height %)
|
||||
:navigate-back? true
|
||||
:background-color (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-90)
|
||||
:height (if platform/ios?
|
||||
(if (> @scroll-height @first-channel-height)
|
||||
134
|
||||
100)
|
||||
(if (> @scroll-height @first-channel-height)
|
||||
140
|
||||
106))}
|
||||
|
||||
[sticky-category-header
|
||||
{:enabled (> @scroll-height @first-channel-height)
|
||||
|
@ -312,4 +319,3 @@
|
|||
[rn/view
|
||||
{:style style/community-overview-container}
|
||||
[community-card-page-view community]]))
|
||||
|
||||
|
|
Loading…
Reference in New Issue