|
| 1 | +(ns status-im2.common.animated-header-list.view |
| 2 | + (:require |
| 3 | + [quo2.core :as quo] |
| 4 | + [react-native.core :as rn] |
| 5 | + [react-native.platform :as platform] |
| 6 | + [react-native.reanimated :as reanimated] |
| 7 | + [react-native.safe-area :as safe-area] |
| 8 | + [reagent.core :as reagent] |
| 9 | + [quo2.foundations.colors :as colors] |
| 10 | + [status-im.ui.components.fast-image :as fast-image] |
| 11 | + [status-im2.common.animated-header-list.style :as style] |
| 12 | + [oops.core :as oops] |
| 13 | + [utils.re-frame :as rf])) |
| 14 | + |
| 15 | +(def header-height 192) |
| 16 | + |
| 17 | +(def threshold (/ header-height 2)) |
| 18 | + |
| 19 | +(defn scroll-handler |
| 20 | + [event initial-y scroll-y opacity-value] |
| 21 | + (let [current-y (- (oops/oget event "nativeEvent.contentOffset.y") initial-y)] |
| 22 | + (reanimated/set-shared-value scroll-y current-y) |
| 23 | + (reanimated/set-shared-value opacity-value |
| 24 | + (reanimated/with-timing (if (> current-y threshold) 1 0))))) |
| 25 | + |
| 26 | +(defn header |
| 27 | + [{:keys [theme-color display-picture-comp cover-uri]} top-inset scroll-y] |
| 28 | + (let [input-range [0 threshold] |
| 29 | + output-range [1 0.4] |
| 30 | + scale-animation (reanimated/interpolate scroll-y |
| 31 | + input-range |
| 32 | + output-range |
| 33 | + {:extrapolateLeft "clamp" |
| 34 | + :extrapolateRight "clamp"})] |
| 35 | + [rn/view |
| 36 | + {:style {:height header-height |
| 37 | + :background-color (or theme-color (colors/theme-colors colors/white colors/neutral-95)) |
| 38 | + :margin-top (when platform/ios? (- top-inset))}} |
| 39 | + (when cover-uri |
| 40 | + [fast-image/fast-image |
| 41 | + {:style {:width "100%" |
| 42 | + :height "100%"} |
| 43 | + :source {:uri cover-uri}}]) |
| 44 | + [rn/view {:style style/header-bottom-part}] |
| 45 | + [reanimated/view {:style (style/entity-picture scale-animation)} |
| 46 | + [display-picture-comp]]])) |
| 47 | + |
| 48 | +(defn animated-header-list |
| 49 | + [{:keys [title-comp theme-color main-comp] :as parameters}] |
| 50 | + [safe-area/consumer |
| 51 | + (fn [insets] |
| 52 | + (let [window-height (:height (rn/get-window)) |
| 53 | + status-bar-height (rn/status-bar-height) |
| 54 | + bottom-inset (:bottom insets) |
| 55 | + ;; view height calculation is different because window height is different on iOS and Android: |
| 56 | + ;; https://i.stack.imgur.com/LSyW5.png |
| 57 | + view-height (if platform/ios? |
| 58 | + (- window-height bottom-inset) |
| 59 | + (+ window-height status-bar-height)) |
| 60 | + input-range [0 threshold] |
| 61 | + output-range [-100 0] |
| 62 | + initial-y (if platform/ios? (- (:top insets)) 0)] |
| 63 | + [:f> |
| 64 | + (fn [] |
| 65 | + (let [scroll-y (reanimated/use-shared-value initial-y) |
| 66 | + translate-animation (reanimated/interpolate scroll-y |
| 67 | + input-range |
| 68 | + output-range |
| 69 | + {:extrapolateLeft "clamp" |
| 70 | + :extrapolateRight "clamp"}) |
| 71 | + opacity-value (reanimated/use-shared-value 0)] |
| 72 | + [rn/view {:style (style/container-view view-height theme-color)} |
| 73 | + [rn/touchable-opacity |
| 74 | + {:active-opacity 1 |
| 75 | + :on-press #(rf/dispatch [:navigate-back]) |
| 76 | + :style (style/button-container {:left 20})} |
| 77 | + [quo/icon :i/arrow-left {:size 20 :color (colors/theme-colors colors/black colors/white)}]] |
| 78 | + [rn/touchable-opacity |
| 79 | + {:active-opacity 1 |
| 80 | + :style (style/button-container {:right 20})} |
| 81 | + [quo/icon :i/options {:size 20 :color (colors/theme-colors colors/black colors/white)}]] |
| 82 | + [reanimated/view {:style (style/title-comp opacity-value)} |
| 83 | + [title-comp]] |
| 84 | + [reanimated/blur-view |
| 85 | + {:blurAmount 32 |
| 86 | + :blurType :light |
| 87 | + :overlayColor (if platform/ios? colors/white-opa-70 :transparent) |
| 88 | + :style (style/blur-view translate-animation)}] |
| 89 | + [reanimated/flat-list |
| 90 | + {:data [nil] |
| 91 | + :render-fn main-comp |
| 92 | + :key-fn (fn [i] (str i)) |
| 93 | + :header (reagent/as-element (header parameters (:top insets) scroll-y)) |
| 94 | + :scroll-event-throttle 8 |
| 95 | + :on-scroll (fn [event] (scroll-handler event initial-y scroll-y opacity-value))}]]))]))]) |
| 96 | + |
| 97 | + |
0 commit comments