showing sticky bar on scrolling discover screen (#14825)

This commit is contained in:
John Ngei 2023-02-06 15:41:34 +03:00 committed by GitHub
parent 89039cd79a
commit 91d0e106f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 325 additions and 127 deletions

View File

@ -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

View File

@ -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

View File

@ -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)}

View File

@ -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]

View File

@ -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])]])))

View File

@ -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})

View File

@ -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]]))

View File

@ -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

View File

@ -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%"

View File

@ -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]]))