[#16709] chat home banner animation (#16823)

* Small typo fix
* Move header-spacing & empty-state to common.home namespace
* Create common animated banner component for chats and communities
* Add animated banner to chats tab
This commit is contained in:
Ulises Manuel Cárdenas 2023-08-03 13:29:44 -06:00 committed by GitHub
parent f6ce63734c
commit 7ad378e9c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 315 additions and 254 deletions

View File

@ -32,7 +32,7 @@
(defn section-list
"A wrapper for SectionList.
To render something on empty sections, use renderSectionFooter and conditionaly
To render something on empty sections, use renderSectionFooter and conditionally
render on empty data
See https://facebook.github.io/react-native/docs/sectionlist.html"
[{:keys [sections render-section-header-fn render-section-footer-fn style] :as props}]

View File

@ -0,0 +1,63 @@
(ns status-im2.common.home.banner.style
(:require [react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]))
(def ^:private card-height (+ 56 16))
(def ^:private max-scroll (+ card-height 8))
(def fill-space
{:position :absolute
:top 0
:right 0
:left 0
:bottom 0})
(defn- animated-card-translation-y
[scroll-shared-value]
(reanimated/interpolate scroll-shared-value [0 max-scroll] [0 (- max-scroll)] :clamp))
(defn banner-card-blur-layer
[scroll-shared-value]
(reanimated/apply-animations-to-style
{:transform [{:translate-y (animated-card-translation-y scroll-shared-value)}]}
{:overflow (if platform/ios? :visible :hidden)
:z-index 1
:position :absolute
:top 0
:right 0
:left 0
:height (+ (safe-area/get-top) 244)}))
(defn banner-card-hiding-layer
[]
{:z-index 2
:position :absolute
:top 0
:right 0
:left 0
:padding-top (safe-area/get-top)})
(def animated-banner-card-container {:overflow :hidden})
(defn animated-banner-card
[scroll-shared-value]
(reanimated/apply-animations-to-style
{:opacity (reanimated/interpolate scroll-shared-value [0 card-height] [1 0] :clamp)
:transform [{:translate-y (animated-card-translation-y scroll-shared-value)}]}
{}))
(defn banner-card-tabs-layer
[scroll-shared-value]
(reanimated/apply-animations-to-style
{:transform [{:translate-y (animated-card-translation-y scroll-shared-value)}]}
{:z-index 3
:position :absolute
:top (+ (safe-area/get-top) 192)
:right 0
:left 0}))
(def banner-card-tabs
{:padding-horizontal 20
:padding-top 8
:padding-bottom 12})

View File

@ -0,0 +1,78 @@
(ns status-im2.common.home.banner.view
(:require [oops.core :as oops]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[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]
[utils.re-frame :as rf]))
(defn- reset-banner-animation
[scroll-shared-value]
(reanimated/animate-shared-value-with-timing scroll-shared-value 0 200 :easing3))
(defn- reset-scroll
[scroll-ref]
(cond
(.-scrollToLocation scroll-ref)
(oops/ocall! scroll-ref "scrollToLocation" #js {:itemIndex 0 :sectionIndex 0 :viewOffset 0})
(.-scrollToOffset scroll-ref)
(oops/ocall! scroll-ref "scrollToOffset" #js {:offset 0})))
(defn- banner-card-blur-layer
[scroll-shared-value]
(let [open-sheet? (-> (rf/sub [:bottom-sheet]) :sheets seq)]
[reanimated/view {:style (style/banner-card-blur-layer scroll-shared-value)}
[blur/view
{:style style/fill-space
:blur-amount (if platform/ios? 20 10)
:blur-type (theme/theme-value (if platform/ios? :light :xlight) :dark)
:overlay-color (if open-sheet?
(colors/theme-colors colors/white colors/neutral-95-opa-70)
(theme/theme-value nil colors/neutral-95-opa-70))}]]))
(defn- banner-card-hiding-layer
[{:keys [title-props card-props scroll-shared-value]}]
(let [customization-color (rf/sub [:profile/customization-color])]
[rn/view {:style (style/banner-card-hiding-layer)}
[common.home/top-nav {:type :grey}]
[common.home/title-column (assoc title-props :customization-color customization-color)]
[rn/view {:style style/animated-banner-card-container}
[reanimated/view {:style (style/animated-banner-card scroll-shared-value)}
[quo/discover-card card-props]]]]))
(defn- banner-card-tabs-layer
[{:keys [selected-tab tabs on-tab-change scroll-ref scroll-shared-value]}]
[reanimated/view {:style (style/banner-card-tabs-layer scroll-shared-value)}
^{:key (str "tabs-" selected-tab)}
[quo/tabs
{:style style/banner-card-tabs
:size 32
:default-active selected-tab
:data tabs
:on-change (fn [tab]
(reset-banner-animation scroll-shared-value)
(some-> scroll-ref
deref
reset-scroll)
(on-tab-change tab))}]])
(defn animated-banner
[{:keys [scroll-ref tabs selected-tab on-tab-change scroll-shared-value content]}]
[:<>
[:f> banner-card-blur-layer scroll-shared-value]
[:f> banner-card-hiding-layer (assoc content :scroll-shared-value scroll-shared-value)]
[:f> banner-card-tabs-layer
{:scroll-shared-value scroll-shared-value
:selected-tab selected-tab
:tabs tabs
:on-tab-change on-tab-change
:scroll-ref scroll-ref}]])
(defn set-scroll-shared-value
[{:keys [shared-value scroll-input]}]
(reanimated/set-shared-value shared-value scroll-input))

View File

@ -1,4 +1,5 @@
(ns status-im2.common.home.style)
(ns status-im2.common.home.style
(:require [react-native.safe-area :as safe-area]))
(def title-column
{:flex-direction :row
@ -44,3 +45,16 @@
(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})

View File

@ -3,12 +3,12 @@
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im2.common.home.style :as style]
[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.re-frame :as rf]
[utils.debounce :refer [dispatch-and-chill]]))
[utils.debounce :refer [dispatch-and-chill]]
[utils.re-frame :as rf]))
(defn title-column
[{:keys [label handler accessibility-label customization-color]}]
@ -130,3 +130,18 @@
[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}]]))

View File

@ -1,5 +1,6 @@
(ns status-im2.contexts.chat.home.style
(:require [react-native.platform :as platform]))
(:require [react-native.platform :as platform]
[react-native.safe-area :as safe-area]))
(def tabs
{:padding-horizontal 20
@ -14,24 +15,11 @@
:bottom 0})
(defn blur-container
[top]
[]
{:overflow (if platform/ios? :visible :hidden)
:position :absolute
:z-index 1
:top 0
:right 0
:left 0
:padding-top top})
(def header-height 245)
(defn header-space
[top]
{:height (+ header-height top)})
(defn empty-content-container
[top]
{:flex 1
:margin-top (+ header-height top)
:margin-bottom 44
:justify-content :center})
:padding-top (safe-area/get-top)})

View File

@ -1,21 +1,18 @@
(ns status-im2.contexts.chat.home.view
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
(:require [oops.core :as oops]
[quo2.theme :as theme]
[re-frame.core :as re-frame]
[react-native.blur :as blur]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.safe-area :as safe-area]
[react-native.reanimated :as reanimated]
[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.resources :as resources]
[status-im2.contexts.chat.actions.view :as home.sheet]
[status-im2.contexts.chat.actions.view :as chat.actions.view]
[status-im2.contexts.chat.home.chat-list-item.view :as chat-list-item]
[status-im2.contexts.chat.home.contact-request.view :as contact-request]
[status-im2.contexts.chat.home.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -30,50 +27,45 @@
(filter k)
(sort-by :timestamp >))))
(defn empty-state-content
[selected-tab]
(case selected-tab
:tab/contacts
{:title (i18n/label :t/no-contacts)
:description (i18n/label :t/no-contacts-description)
:image (resources/get-image
(theme/theme-value :no-contacts-light :no-contacts-dark))}
:tab/groups
{:title (i18n/label :t/no-group-chats)
:description (i18n/label :t/no-group-chats-description)
:image (resources/get-image
(theme/theme-value :no-group-chats-light :no-group-chats-dark))}
:tab/recent
{:title (i18n/label :t/no-messages)
:description (i18n/label :t/no-messages-description)
:image (resources/get-image
(theme/theme-value :no-messages-light :no-messages-dark))}
nil))
(defn empty-state
[{:keys [selected-tab top]}]
(let [{:keys [image title description]} (empty-state-content selected-tab)]
[rn/view {:style (style/empty-content-container top)}
[quo/empty-state
{:image image
:title title
:description description}]]))
(def empty-state-content
#:tab{:contacts
{:title (i18n/label :t/no-contacts)
:description (i18n/label :t/no-contacts-description)
:image (resources/get-image
(theme/theme-value :no-contacts-light :no-contacts-dark))}
:groups
{:title (i18n/label :t/no-group-chats)
:description (i18n/label :t/no-group-chats-description)
:image (resources/get-image
(theme/theme-value :no-group-chats-light :no-group-chats-dark))}
:recent
{:title (i18n/label :t/no-messages)
:description (i18n/label :t/no-messages-description)
:image (resources/get-image
(theme/theme-value :no-messages-light :no-messages-dark))}})
(defn chats
[selected-tab top]
[{:keys [selected-tab set-scroll-ref scroll-shared-value]}]
(let [unfiltered-items (rf/sub [:chats-stack-items])
items (filter-and-sort-items-by-tab selected-tab unfiltered-items)]
(if (empty? items)
[empty-state {:top top :selected-tab selected-tab}]
[rn/flat-list
{:key-fn #(or (:chat-id %) (:public-key %) (:id %))
[common.home/empty-state-image
{:selected-tab selected-tab
:tab->content empty-state-content}]
[reanimated/flat-list
{:ref set-scroll-ref
:key-fn #(or (:chat-id %) (:public-key %) (:id %))
:content-inset-adjustment-behavior :never
:header [rn/view {:style (style/header-space top)}]
:header [common.home/header-spacing]
: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}])))
:render-fn chat-list-item/chat-list-item
:scroll-event-throttle 8
:on-scroll #(common.home.banner/set-scroll-shared-value
{:scroll-input (oops/oget % "nativeEvent.contentOffset.y")
:shared-value scroll-shared-value})}])))
(defn contact-item-render
[{:keys [public-key] :as item}]
@ -89,23 +81,30 @@
item]))
(defn contacts
[pending-contact-requests top]
[{:keys [pending-contact-requests set-scroll-ref scroll-shared-value]}]
(let [items (rf/sub [:contacts/active-sections])]
(if (and (empty? items) (empty? pending-contact-requests))
[empty-state {:top top :selected-tab :tab/contacts}]
[common.home/empty-state-image
{:selected-tab :tab/contacts
:tab->content empty-state-content}]
[rn/section-list
{:key-fn :public-key
{:ref set-scroll-ref
:key-fn :public-key
:get-item-layout get-item-layout
:content-inset-adjustment-behavior :never
:header [:<>
[rn/view {:style (style/header-space top)}]
[common.home/header-spacing]
(when (seq pending-contact-requests)
[contact-request/contact-requests
pending-contact-requests])]
:sections items
:sticky-section-headers-enabled false
:render-section-header-fn contact-list/contacts-section-header
:render-fn contact-item-render}])))
:render-fn contact-item-render
:scroll-event-throttle 8
:on-scroll #(common.home.banner/set-scroll-shared-value
{:scroll-input (oops/oget % "nativeEvent.contentOffset.y")
:shared-value scroll-shared-value})}])))
(defn get-tabs-data
[dot?]
@ -116,41 +115,39 @@
:accessibility-label :tab-contacts
:notification-dot? dot?}])
(def ^:private banner-data
{:title-props
{:label (i18n/label :t/messages)
:handler #(rf/dispatch
[:show-bottom-sheet {:content chat.actions.view/new-chat}])
:accessibility-label :new-chat-button}
:card-props
{:banner (resources/get-image :invite-friends)
:title (i18n/label :t/invite-friends-to-status)
:description (i18n/label :t/share-invite-link)}})
(defn home
[]
(let [pending-contact-requests (rf/sub [:activity-center/pending-contact-requests])
selected-tab (or (rf/sub [:messages-home/selected-tab]) :tab/recent)
customization-color (rf/sub [:profile/customization-color])
top (safe-area/get-top)]
[:<>
(if (= selected-tab :tab/contacts)
[contacts pending-contact-requests top]
[chats selected-tab top])
[rn/view {:style (style/blur-container top)}
(let [{:keys [sheets]} (rf/sub [:bottom-sheet])]
[blur/view
{:blur-amount (if platform/ios? 20 10)
:blur-type (if (colors/dark?) :dark (if platform/ios? :light :xlight))
:style style/blur
:overlay-color (if (seq sheets)
(theme/theme-value colors/white colors/neutral-95-opa-70)
(when (colors/dark?)
colors/neutral-95-opa-70))}])
[common.home/top-nav {:type :grey}]
[common.home/title-column
{:label (i18n/label :t/messages)
:handler #(rf/dispatch [:show-bottom-sheet {:content home.sheet/new-chat}])
:accessibility-label :new-chat-button
:customization-color customization-color}]
[quo/discover-card
{:banner (resources/get-image :invite-friends)
:title (i18n/label :t/invite-friends-to-status)
:description (i18n/label :t/share-invite-link)}]
^{:key (str "tabs-" selected-tab)}
[quo/tabs
{:style style/tabs
:size 32
:on-change (fn [tab]
(rf/dispatch [:messages-home/select-tab tab]))
:default-active selected-tab
:data (get-tabs-data (pos? (count pending-contact-requests)))}]]]))
(let [scroll-ref (atom nil)
set-scroll-ref #(reset! scroll-ref %)]
(fn []
(let [pending-contact-requests (rf/sub [:activity-center/pending-contact-requests])
selected-tab (or (rf/sub [:messages-home/selected-tab]) :tab/recent)
scroll-shared-value (reanimated/use-shared-value 0)]
[:<>
(if (= selected-tab :tab/contacts)
[contacts
{:pending-contact-requests pending-contact-requests
:set-scroll-ref set-scroll-ref
:scroll-shared-value scroll-shared-value}]
[chats
{:selected-tab selected-tab
:set-scroll-ref set-scroll-ref
:scroll-shared-value scroll-shared-value}])
[:f> common.home.banner/animated-banner
{:content banner-data
:scroll-ref scroll-ref
:tabs (get-tabs-data (pos? (count pending-contact-requests)))
:selected-tab selected-tab
:on-tab-change (fn [tab] (rf/dispatch [:messages-home/select-tab tab]))
:scroll-shared-value scroll-shared-value}]]))))

View File

@ -1,10 +1,8 @@
(ns status-im2.contexts.communities.home.style
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]
[react-native.safe-area :as safe-area]
[react-native.reanimated :as reanimated]))
(def header-height 245)
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]))
(def tabs
{:padding-horizontal 20
@ -18,22 +16,11 @@
:left 0
:bottom 0})
(defn empty-state-container
[]
{:margin-top (+ header-height (safe-area/get-top))
:margin-bottom 44
:flex 1
:justify-content :center})
(def empty-state-placeholder
{:height 120
:width 120
:background-color colors/danger-50})
(defn header-spacing
[]
{:height (+ header-height (safe-area/get-top))})
(defn blur-banner-layer
[animated-translation-y]
(let [fixed-height (+ (safe-area/get-top) 244)]

View File

@ -1,17 +1,14 @@
(ns status-im2.contexts.communities.home.view
(:require [oops.core :as oops]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[react-native.platform :as platform]
[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.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]
[status-im2.contexts.communities.home.style :as style]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.number]
@ -40,122 +37,43 @@
{:id :pending :label (i18n/label :t/pending) :accessibility-label :pending-tab}
{:id :opened :label (i18n/label :t/opened) :accessibility-label :opened-tab}])
(defn empty-state-content
[selected-tab]
(case selected-tab
:joined
{:title (i18n/label :t/no-communities)
:description [:<>
[rn/text {:style {:text-decoration-line :line-through}}
(i18n/label :t/no-communities-description-strikethrough)]
" "
(i18n/label :t/no-communities-description)]
:image (resources/get-image (theme/theme-value :no-communities-light
:no-communities-dark))}
:pending
{:title (i18n/label :t/no-pending-communities)
:description (i18n/label :t/no-pending-communities-description)
:image (resources/get-image (theme/theme-value :no-pending-communities-light
:no-pending-communities-dark))}
:opened
{:title (i18n/label :t/no-opened-communities)
:description (i18n/label :t/no-opened-communities-description)
:image (resources/get-image (theme/theme-value :no-opened-communities-light
:no-opened-communities-dark))}
nil))
(def empty-state-content
{:joined
{:title (i18n/label :t/no-communities)
:description [:<>
[rn/text {:style {:text-decoration-line :line-through}}
(i18n/label :t/no-communities-description-strikethrough)]
" "
(i18n/label :t/no-communities-description)]
:image (resources/get-image (theme/theme-value :no-communities-light
:no-communities-dark))}
:pending
{:title (i18n/label :t/no-pending-communities)
:description (i18n/label :t/no-pending-communities-description)
:image (resources/get-image (theme/theme-value :no-pending-communities-light
:no-pending-communities-dark))}
:opened
{:title (i18n/label :t/no-opened-communities)
:description (i18n/label :t/no-opened-communities-description)
:image (resources/get-image (theme/theme-value :no-opened-communities-light
:no-opened-communities-dark))}})
(defn- empty-state
[{:keys [style selected-tab]}]
(let [{:keys [image title description]} (empty-state-content selected-tab)
customization-color (rf/sub [:profile/customization-color])]
[rn/view {:style style}
[quo/empty-state
{:customization-color customization-color
:image image
:title title
:description description}]]))
(defn- blur-banner-layer
[animated-translation-y]
(let [open-sheet? (-> (rf/sub [:bottom-sheet]) :sheets seq)]
[reanimated/view {:style (style/blur-banner-layer animated-translation-y)}
[blur/view
{:blur-amount (if platform/ios? 20 10)
:blur-type (theme/theme-value (if platform/ios? :light :xlight) :dark)
:style style/blur
:overlay-color (if open-sheet?
(colors/theme-colors colors/white colors/neutral-95-opa-70)
(theme/theme-value nil colors/neutral-95-opa-70))}]]))
(defn- hiding-banner-layer
[animated-translation-y animated-opacity]
(let [customization-color (rf/sub [:profile/customization-color])]
[rn/view {:style (style/hiding-banner-layer)}
[common.home/top-nav {:type :grey}]
[common.home/title-column
{:label (i18n/label :t/communities)
:handler #(rf/dispatch
[:show-bottom-sheet {:content actions.home-plus/view}])
:accessibility-label :new-communities-button
:customization-color customization-color}]
[rn/view {:style style/animated-card-container}
[reanimated/view {:style (style/animated-card animated-opacity animated-translation-y)}
[quo/discover-card
{:on-press #(rf/dispatch [:navigate-to :discover-communities])
:title (i18n/label :t/discover)
:description (i18n/label :t/favorite-communities)
:banner (resources/get-image :discover)
:accessibility-label :communities-home-discover-card}]]]]))
(defn- reset-banner-animation
[animated-opacity animated-translation-y]
(reanimated/animate-shared-value-with-timing animated-opacity 1 200 :easing3)
(reanimated/animate-shared-value-with-timing animated-translation-y 0 200 :easing3))
(defn- reset-scroll
[flat-list-ref]
(some-> flat-list-ref
(.scrollToOffset #js {:offset 0 :animated? true})))
(defn- tabs-banner-layer
[animated-translation-y animated-opacity selected-tab flat-list-ref]
(let [on-tab-change (fn [tab]
(if (empty? (get (rf/sub [:communities/grouped-by-status]) tab))
(reset-banner-animation animated-opacity animated-translation-y)
(reset-scroll @flat-list-ref))
(rf/dispatch [:communities/select-tab tab]))]
[reanimated/view {:style (style/tabs-banner-layer animated-translation-y)}
^{:key (str "tabs-" selected-tab)}
[quo/tabs
{:size 32
:style style/tabs
:on-change on-tab-change
:default-active selected-tab
:data tabs-data}]]))
(defn- animated-banner
[{:keys [selected-tab animated-translation-y animated-opacity flat-list-ref]}]
[:<>
[:f> blur-banner-layer animated-translation-y]
[:f> hiding-banner-layer animated-translation-y animated-opacity]
[:f> tabs-banner-layer animated-translation-y animated-opacity selected-tab flat-list-ref]])
(def ^:private card-height (+ 56 16)) ; Card height + its vertical margins
(def ^:private card-opacity-factor (/ 100 card-height 100))
(def ^:private max-scroll (- (+ card-height 8))) ; added 8 from tabs top padding
(defn- set-animated-banner-values
[{:keys [scroll-offset translation-y opacity]}]
(let [new-opacity (-> (* (- card-height scroll-offset) card-opacity-factor)
(utils.number/value-in-range 0 1))
new-translation-y (-> (- scroll-offset)
(utils.number/value-in-range max-scroll 0))]
(reanimated/animate-shared-value-with-timing opacity new-opacity 80 :easing4)
(reanimated/animate-shared-value-with-timing translation-y new-translation-y 80 :easing4)))
(def ^:private banner-data
{:title-props
{:label (i18n/label :t/communities)
:handler #(rf/dispatch [:show-bottom-sheet {:content actions.home-plus/view}])
:accessibility-label :new-communities-button}
:card-props
{:on-press #(rf/dispatch [:navigate-to :discover-communities])
:title (i18n/label :t/discover)
:description (i18n/label :t/favorite-communities)
:banner (resources/get-image :discover)
:accessibility-label :communities-home-discover-card}})
(defn home
[]
(let [flat-list-ref (atom nil)]
(let [flat-list-ref (atom nil)
set-flat-list-ref #(reset! flat-list-ref %)]
(fn []
(let [selected-tab (or (rf/sub [:communities/selected-tab]) :joined)
{:keys [joined pending opened]} (rf/sub [:communities/grouped-by-status])
@ -163,28 +81,29 @@
:joined joined
:pending pending
:opened opened)
animated-opacity (reanimated/use-shared-value 1)
animated-translation-y (reanimated/use-shared-value 0)]
scroll-shared-value (reanimated/use-shared-value 0)]
[:<>
(if (empty? selected-items)
[empty-state
{:style (style/empty-state-container)
:selected-tab selected-tab}]
[rn/flat-list
{:ref #(reset! flat-list-ref %)
[common.home/empty-state-image
{:selected-tab selected-tab
:tab->content empty-state-content}]
[reanimated/flat-list
{:ref set-flat-list-ref
:key-fn :id
:content-inset-adjustment-behavior :never
:header [rn/view {:style (style/header-spacing)}]
:header [common.home/header-spacing]
:render-fn item-render
:data selected-items
:on-scroll #(set-animated-banner-values
{:scroll-offset (oops/oget
%
"nativeEvent.contentOffset.y")
:translation-y animated-translation-y
:opacity animated-opacity})}])
[:f> animated-banner
{:selected-tab selected-tab
:animated-translation-y animated-translation-y
:animated-opacity animated-opacity
:flat-list-ref flat-list-ref}]]))))
:scroll-event-throttle 8
:on-scroll #(common.home.banner/set-scroll-shared-value
{:scroll-input (oops/oget
%
"nativeEvent.contentOffset.y")
:shared-value scroll-shared-value})}])
[:f> common.home.banner/animated-banner
{:content banner-data
:scroll-ref flat-list-ref
:tabs tabs-data
:selected-tab selected-tab
:on-tab-change (fn [tab] (rf/dispatch [:communities/select-tab tab]))
:scroll-shared-value scroll-shared-value}]]))))

View File

@ -28,7 +28,7 @@
(get shell.constants/stacks-z-index-keywords stack-id))})}
(case stack-id
:communities-stack [:f> communities/home]
:chats-stack [chat/home]
:chats-stack [:f> chat/home]
:wallet-stack [wallet.accounts/accounts-overview-old]
:browser-stack [browser.stack/browser-stack]
[:<>])])