|
| 1 | +(ns status-im2.common.floating-button-page.view |
| 2 | + (:require |
| 3 | + [oops.core :as oops] |
| 4 | + [react-native.core :as rn] |
| 5 | + [react-native.platform :as platform] |
| 6 | + [react-native.safe-area :as safe-area] |
| 7 | + [reagent.core :as reagent] |
| 8 | + [status-im2.common.floating-button-page.floating-container.view :as floating-container] |
| 9 | + [status-im2.common.floating-button-page.style :as style])) |
| 10 | + |
| 11 | +(defn- show-background |
| 12 | + [{:keys [window-height keyboard-height footer-container-height content-scroll-y |
| 13 | + content-container-height header-height keyboard-shown?]}] |
| 14 | + (let [available-space (- window-height |
| 15 | + (safe-area/get-top) |
| 16 | + header-height |
| 17 | + keyboard-height ; Already contains the bottom safe area value |
| 18 | + footer-container-height) |
| 19 | + scroll-view-height (- content-container-height content-scroll-y) |
| 20 | + overlap? (< available-space scroll-view-height)] |
| 21 | + (and keyboard-shown? overlap?))) |
| 22 | + |
| 23 | +(defn- set-height-on-layout |
| 24 | + [ratom] |
| 25 | + (fn [event] |
| 26 | + (let [height (oops/oget event "nativeEvent.layout.height")] |
| 27 | + (reset! ratom height)))) |
| 28 | + |
| 29 | +(defn- init-keyboard-listeners |
| 30 | + [{:keys [on-did-show]}] |
| 31 | + (let [keyboard-will-show? (reagent/atom false) |
| 32 | + keyboard-did-show? (reagent/atom false) |
| 33 | + add-listener (fn [listener callback] |
| 34 | + (oops/ocall rn/keyboard "addListener" listener callback)) |
| 35 | + will-show-listener (add-listener "keyboardWillShow" |
| 36 | + #(reset! keyboard-will-show? true)) |
| 37 | + did-show-listener (add-listener "keyboardDidShow" |
| 38 | + (fn [e] |
| 39 | + (reset! keyboard-did-show? true) |
| 40 | + (when on-did-show (on-did-show e)))) |
| 41 | + will-hide-listener (add-listener "keyboardWillHide" |
| 42 | + #(reset! keyboard-will-show? false)) |
| 43 | + did-hide-listener (add-listener "keyboardDidHide" |
| 44 | + #(reset! keyboard-did-show? false)) |
| 45 | + remove-listeners (fn [] |
| 46 | + (doseq [listener [will-show-listener will-hide-listener |
| 47 | + did-show-listener did-hide-listener]] |
| 48 | + (oops/ocall listener "remove")))] |
| 49 | + {:keyboard-will-show? keyboard-will-show? |
| 50 | + :keyboard-did-show? keyboard-did-show? |
| 51 | + :remove-listeners remove-listeners})) |
| 52 | + |
| 53 | +(defn view |
| 54 | + [{:keys [header footer]} & children] |
| 55 | + (reagent/with-let [window-height (:height (rn/get-window)) |
| 56 | + footer-container-height (reagent/atom 0) |
| 57 | + header-height (reagent/atom 0) |
| 58 | + content-container-height (reagent/atom 0) |
| 59 | + content-scroll-y (reagent/atom 0) |
| 60 | + keyboard-height (reagent/atom 0) |
| 61 | + {:keys [keyboard-will-show? |
| 62 | + keyboard-did-show? |
| 63 | + remove-listeners]} (init-keyboard-listeners |
| 64 | + {:on-did-show |
| 65 | + (fn [e] |
| 66 | + (reset! keyboard-height |
| 67 | + (oops/oget e "endCoordinates.height")))}) |
| 68 | + set-header-height (set-height-on-layout header-height) |
| 69 | + set-content-container-height (set-height-on-layout content-container-height) |
| 70 | + set-footer-container-height (set-height-on-layout footer-container-height) |
| 71 | + set-content-y-scroll (fn [event] |
| 72 | + (reset! content-scroll-y |
| 73 | + (oops/oget event "nativeEvent.contentOffset.y")))] |
| 74 | + (let [keyboard-shown? (if platform/ios? @keyboard-will-show? @keyboard-did-show?) |
| 75 | + show-background? (show-background {:window-height window-height |
| 76 | + :footer-container-height @footer-container-height |
| 77 | + :keyboard-height @keyboard-height |
| 78 | + :content-scroll-y @content-scroll-y |
| 79 | + :content-container-height @content-container-height |
| 80 | + :header-height @header-height |
| 81 | + :keyboard-shown? keyboard-shown?})] |
| 82 | + |
| 83 | + [rn/view {:style style/page-container} |
| 84 | + [rn/view {:on-layout set-header-height} |
| 85 | + header] |
| 86 | + [rn/scroll-view |
| 87 | + {:on-scroll set-content-y-scroll |
| 88 | + :scroll-event-throttle 64 |
| 89 | + :content-container-style {:flex-grow 1}} |
| 90 | + (into [rn/view {:on-layout set-content-container-height}] |
| 91 | + children)] |
| 92 | + [rn/keyboard-avoiding-view |
| 93 | + {:style style/keyboard-avoiding-view |
| 94 | + :keyboard-vertical-offset (if platform/ios? (safe-area/get-top) 0) |
| 95 | + :pointer-events :box-none} |
| 96 | + [floating-container/view |
| 97 | + {:on-layout set-footer-container-height |
| 98 | + :keyboard-shown? keyboard-shown? |
| 99 | + :blur? show-background?} |
| 100 | + footer]]]) |
| 101 | + (finally |
| 102 | + (remove-listeners)))) |
0 commit comments