From 91d0e106f270a0f4eb77fd07cb147f14897ff90c Mon Sep 17 00:00:00 2001 From: John Ngei Date: Mon, 6 Feb 2023 15:41:34 +0300 Subject: [PATCH] showing sticky bar on scrolling discover screen (#14825) --- ios/Podfile.lock | 8 +- src/quo2/components/buttons/button.cljs | 3 +- .../community/community_card_view.cljs | 2 +- src/status_im2/common/scroll_page/style.cljs | 27 ++- src/status_im2/common/scroll_page/view.cljs | 109 +++++---- .../contexts/communities/discover/style.cljs | 55 +++++ .../contexts/communities/discover/view.cljs | 211 +++++++++++++----- .../contexts/communities/home/view.cljs | 3 +- .../contexts/communities/overview/style.cljs | 12 +- .../contexts/communities/overview/view.cljs | 22 +- 10 files changed, 325 insertions(+), 127 deletions(-) create mode 100644 src/status_im2/contexts/communities/discover/style.cljs diff --git a/ios/Podfile.lock b/ios/Podfile.lock index da6235de2a..75381935b6 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -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 diff --git a/src/quo2/components/buttons/button.cljs b/src/quo2/components/buttons/button.cljs index 85a3917a1e..1f395d7d66 100644 --- a/src/quo2/components/buttons/button.cljs +++ b/src/quo2/components/buttons/button.cljs @@ -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 diff --git a/src/quo2/components/community/community_card_view.cljs b/src/quo2/components/community/community_card_view.cljs index 923a8f5304..c1176ecaf8 100644 --- a/src/quo2/components/community/community_card_view.cljs +++ b/src/quo2/components/community/community_card_view.cljs @@ -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)} diff --git a/src/status_im2/common/scroll_page/style.cljs b/src/status_im2/common/scroll_page/style.cljs index 5ce94a92e1..316b804cd5 100644 --- a/src/status_im2/common/scroll_page/style.cljs +++ b/src/status_im2/common/scroll_page/style.cljs @@ -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})) + {:z-index 5 + :position :absolute + :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] diff --git a/src/status_im2/common/scroll_page/view.cljs b/src/status_im2/common/scroll_page/view.cljs index 3612a4ed3a..a421721a52 100644 --- a/src/status_im2/common/scroll_page/view.cljs +++ b/src/status_im2/common/scroll_page/view.cljs @@ -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,35 +55,41 @@ [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)}} - [reanimated/view - {:style (style/sticky-header-title opacity-animation)} - [rn/image - {:source cover - :style style/sticky-header-image}] - [quo/text - {:size :paragraph-1 - :weight :semi-bold - :style {:line-height 21}} - name]] - [quo/page-nav - {: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 + (when cover + [reanimated/view + {:style (style/sticky-header-title opacity-animation)} + [rn/image + {:source cover + :style style/sticky-header-image}] + [quo/text + {:size :paragraph-1 + :weight :semi-bold + :style {:line-height 21}} + name]]) + (if top-nav + [top-nav] + [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 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]} - sticky-header - children] + (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)))} - [rn/view {:style {:height 151}} - [rn/image - {:source cover-image - :style {:overflow :visible - :flex 1}}]] + (when cover-image + [rn/view {:style {:height 151}} + [rn/image + {:source cover-image + :style {:overflow :visible + :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])]]))) diff --git a/src/status_im2/contexts/communities/discover/style.cljs b/src/status_im2/contexts/communities/discover/style.cljs new file mode 100644 index 0000000000..f24e0a83fd --- /dev/null +++ b/src/status_im2/contexts/communities/discover/style.cljs @@ -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}) diff --git a/src/status_im2/contexts/communities/discover/view.cljs b/src/status_im2/contexts/communities/discover/view.cljs index da7706970f..d7ce10453d 100644 --- a/src/status_im2/contexts/communities/discover/view.cljs +++ b/src/status_im2/contexts/communities/discover/view.cljs @@ -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 [] - [rn/view - {:style {:margin-left 20 - :margin-right 20 - :flex 1 - :background-color (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]])])))) + (let [featured-communities (rf/sub [:communities/featured-communities])] + [rn/view + {:style (style/discover-screen-container (colors/theme-colors + colors/white + colors/neutral-95))} + [discover-screen-content featured-communities]])) \ No newline at end of file diff --git a/src/status_im2/contexts/communities/home/view.cljs b/src/status_im2/contexts/communities/home/view.cljs index 4416bd0fd6..32d44dd70e 100644 --- a/src/status_im2/contexts/communities/home/view.cljs +++ b/src/status_im2/contexts/communities/home/view.cljs @@ -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 diff --git a/src/status_im2/contexts/communities/overview/style.cljs b/src/status_im2/contexts/communities/overview/style.cljs index 8273ab16df..2e6bb0b880 100644 --- a/src/status_im2/contexts/communities/overview/style.cljs +++ b/src/status_im2/contexts/communities/overview/style.cljs @@ -8,11 +8,13 @@ :margin-top 20}) (def blur-channel-header - {:position :absolute - :top (if platform/ios? 56 60) - :height 34 - :width "100%" - :flex 1}) + {:position :absolute + :top (if platform/ios? 56 60) + :height 34 + :right 0 + :left 0 + :flex 1 + :background-color :transparent}) (def join-button {:width "100%" diff --git a/src/status_im2/contexts/communities/overview/view.cljs b/src/status_im2/contexts/communities/overview/view.cljs index 35151a7e3d..f2409c9164 100644 --- a/src/status_im2/contexts/communities/overview/view.cljs +++ b/src/status_im2/contexts/communities/overview/view.cljs @@ -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]])) -