From cd69d0423a005853bcb7db4ff06186bf1677a763 Mon Sep 17 00:00:00 2001 From: flexsurfer Date: Tue, 25 Apr 2023 15:13:14 +0200 Subject: [PATCH] fix (fn[]) usage in hiccup (#15713) --- ios/Podfile.lock | 18 +- package.json | 2 +- src/mocks/js_dependencies.cljs | 7 +- src/quo/components/animated_header.cljs | 16 +- src/quo/components/bottom_sheet/view.cljs | 6 +- src/quo/components/safe_area.cljs | 23 -- src/quo/core.cljs | 4 - .../animated_header_flatlist/view.cljs | 91 +++-- src/quo2/components/code/snippet.cljs | 6 +- src/quo2/components/dropdowns/dropdown.cljs | 179 +++++----- .../links/url_preview_list/view.cljs | 4 +- src/quo2/components/loaders/skeleton.cljs | 111 +++--- src/quo2/components/messages/author/view.cljs | 112 +++--- .../components/messages/system_message.cljs | 56 +-- .../components/navigation/bottom_nav_tab.cljs | 126 +++---- .../navigation/floating_shell_button.cljs | 64 ++-- .../components/profile/profile_card/view.cljs | 6 +- .../record_audio/buttons/delete_button.cljs | 160 ++++----- .../record_audio/buttons/lock_button.cljs | 142 ++++---- .../record_audio/buttons/record_button.cljs | 34 +- .../buttons/record_button_big.cljs | 338 +++++++++--------- .../record_audio/buttons/send_button.cljs | 166 +++++---- .../record_audio/record_audio/view.cljs | 127 ++++--- .../__tests__/soundtrack_component_spec.cljs | 8 +- .../record_audio/soundtrack/view.cljs | 50 ++- src/react_native/core.cljs | 26 +- src/react_native/safe_area.cljs | 47 +-- src/status_im/bottom_sheet/view.cljs | 237 ++++++------ .../keyboard_avoid_presentation.cljs | 24 +- src/status_im/ui/components/react.cljs | 5 - src/status_im/ui/components/topbar.cljs | 31 +- src/status_im/ui/screens/browser/stack.cljs | 14 +- .../ui/screens/chat/components/accessory.cljs | 8 +- .../ui/screens/chat/components/hooks.cljs | 8 +- .../ui/screens/chat/image/preview/views.cljs | 46 ++- .../ui/screens/wallet/accounts/views.cljs | 59 ++- .../chat/components/new_chat/view.cljs | 116 +++--- .../screens/chat/pin_limit_popover/view.cljs | 61 ---- src/status_im2/common/bottom_sheet/view.cljs | 2 +- .../common/bottom_sheet_screen/view.cljs | 65 ++-- src/status_im2/common/scroll_page/view.cljs | 8 +- .../common/sticky_scroll_view/view.cljs | 100 ------ src/status_im2/common/toasts/view.cljs | 108 +++--- src/status_im2/contexts/chat/home/view.cljs | 57 ++- .../chat/menus/pinned_messages/view.cljs | 84 +++-- .../chat/messages/composer/mentions/view.cljs | 48 ++- .../contexts/chat/messages/composer/view.cljs | 144 ++++---- .../chat/messages/content/album/view.cljs | 114 +++--- .../chat/messages/content/image/view.cljs | 44 ++- .../contexts/chat/messages/view.cljs | 23 +- .../photo_selector/album_selector/view.cljs | 42 +-- .../contexts/communities/home/view.cljs | 63 ++-- .../onboarding/common/background/view.cljs | 30 +- .../onboarding/common/carousel/view.cljs | 75 ++-- .../onboarding/create_password/view.cljs | 35 +- .../onboarding/create_profile/view.cljs | 196 +++++----- .../onboarding/enable_biometrics/view.cljs | 18 +- .../onboarding/enable_notifications/view.cljs | 20 +- .../onboarding/enter_seed_phrase/view.cljs | 10 +- .../onboarding/generating_keys/view.cljs | 10 +- .../onboarding/new_to_status/view.cljs | 24 +- .../contexts/onboarding/sign_in/view.cljs | 136 +++---- .../syncing/syncing_devices/view.cljs | 9 +- .../contexts/onboarding/welcome/view.cljs | 33 +- .../animated_header_list.cljs | 24 +- .../navigation/bottom_nav_tab.cljs | 33 +- .../navigation/floating_shell_button.cljs | 23 +- .../contexts/shell/bottom_tabs.cljs | 52 +-- src/status_im2/contexts/shell/constants.cljs | 8 +- src/status_im2/contexts/shell/home_stack.cljs | 73 ++-- src/status_im2/contexts/shell/view.cljs | 67 ++-- .../contexts/syncing/setup_syncing/view.cljs | 156 ++++---- src/status_im2/navigation/view.cljs | 81 ++--- test/jest/jest.config.js | 2 +- yarn.lock | 10 +- 75 files changed, 2145 insertions(+), 2420 deletions(-) delete mode 100644 src/quo/components/safe_area.cljs delete mode 100644 src/status_im/ui2/screens/chat/pin_limit_popover/view.cljs delete mode 100644 src/status_im2/common/sticky_scroll_view/view.cljs diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 86c6f0481d..d438f999fd 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -256,8 +256,6 @@ PODS: - React-Core - react-native-randombytes (3.6.1): - React-Core - - react-native-safe-area-context (2.0.0): - - React - react-native-shake (3.4.0): - React - react-native-slider (3.0.0): @@ -412,6 +410,8 @@ PODS: - Yoga - RNShare (7.0.1): - React-Core + - RNStaticSafeAreaInsets (2.2.0): + - React-Core - RNSVG (9.13.6): - React - SDWebImage (5.11.1): @@ -468,7 +468,6 @@ DEPENDENCIES: - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`) - react-native-randombytes (from `../node_modules/react-native-randombytes`) - - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-shake (from `../node_modules/react-native-shake`) - "react-native-slider (from `../node_modules/@react-native-community/slider`)" - react-native-status (from `../modules/react-native-status`) @@ -503,6 +502,7 @@ DEPENDENCIES: - RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNShare (from `../node_modules/react-native-share`) + - RNStaticSafeAreaInsets (from `../node_modules/react-native-static-safe-area-insets`) - RNSVG (from `../node_modules/react-native-svg`) - secp256k1 (from `https://github.com/status-im/secp256k1.swift.git`) - SQLCipher (~> 3.0) @@ -589,8 +589,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-orientation-locker" react-native-randombytes: :path: "../node_modules/react-native-randombytes" - react-native-safe-area-context: - :path: "../node_modules/react-native-safe-area-context" react-native-shake: :path: "../node_modules/react-native-shake" react-native-slider: @@ -659,6 +657,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-reanimated" RNShare: :path: "../node_modules/react-native-share" + RNStaticSafeAreaInsets: + :path: "../node_modules/react-native-static-safe-area-insets" RNSVG: :path: "../node_modules/react-native-svg" secp256k1: @@ -682,11 +682,11 @@ SPEC CHECKSUMS: boost: a7c83b31436843459a1961bfd74b96033dc77234 BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 CryptoSwift: c4f2debceb38bf44c80659afe009f71e23e4a082 - DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 + DoubleConversion: cde416483dac037923206447da6e1454df403714 FBLazyVector: d2db9d00883282819d03bbd401b2ad4360d47580 FBReactNativeSpec: 94da4d84ba3b1acf459103320882daa481a2b62d fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 - glog: 9e3310013355e9221591364060e841c28041dfe3 + glog: 997518ea2aa2d8cd5df9797b641b758d52ecf2bc HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352 Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8 libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef @@ -716,7 +716,6 @@ SPEC CHECKSUMS: react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9 react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846 - react-native-safe-area-context: 60f654e00b6cc416573f6d5dbfce3839958eb57a react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4 react-native-status: 21f75d492fd311dc111303da38a7a2b23a8a8466 @@ -751,6 +750,7 @@ SPEC CHECKSUMS: RNReactNativeHapticFeedback: 2566b468cc8d0e7bb2f84b23adc0f4614594d071 RNReanimated: 3ad6ec4e147462206be9d1c925df10b6ea850b0e RNShare: 2dc2fcac3f7321cfd6b60a23ed4bf4d549f86f5f + RNStaticSafeAreaInsets: 055ddbf5e476321720457cdaeec0ff2ba40ec1b8 RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d @@ -763,4 +763,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: c29de3b14e3275299c51aa95520622f09d084bcb -COCOAPODS: 1.12.0 +COCOAPODS: 1.12.1 diff --git a/package.json b/package.json index fdb2c3df35..859d4b6eff 100644 --- a/package.json +++ b/package.json @@ -63,9 +63,9 @@ "react-native-randombytes": "^3.6.1", "react-native-reanimated": "2.3.3", "react-native-redash": "^16.0.11", - "react-native-safe-area-context": "^2.0.0", "react-native-shake": "^3.3.1", "react-native-share": "^7.0.1", + "react-native-static-safe-area-insets": "^2.2.0", "react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39", "react-native-svg": "^9.8.4", "react-native-touch-id": "^4.4.1", diff --git a/src/mocks/js_dependencies.cljs b/src/mocks/js_dependencies.cljs index baad343f27..d56a34a5ca 100644 --- a/src/mocks/js_dependencies.cljs +++ b/src/mocks/js_dependencies.cljs @@ -155,10 +155,7 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return ( (def net-info #js {}) (def touchid #js {}) (def react-native-image-viewing #js {:default {}}) -(def safe-area-context - (clj->js {:SafeAreaProvider {:_reactNativeIphoneXHelper {:getStatusBarHeight (fn [])}} - :SafeAreaInsetsContext {:Consumer (fn [])} - :SafeAreaView {}})) +(def react-native-static-safe-area-insets #js {:default {}}) (def back-handler #js @@ -367,7 +364,7 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return ( "react-native-background-timer" background-timer "react-native-image-crop-picker" image-crop-picker "react-native-gesture-handler" react-native-gesture-handler - "react-native-safe-area-context" safe-area-context + "react-native-static-safe-area-insets" react-native-static-safe-area-insets "react-native-config" config "react-native-iphone-x-helper" (clj->js {:getStatusBarHeight (fn []) :getBottomSpace (fn [])}) diff --git a/src/quo/components/animated_header.cljs b/src/quo/components/animated_header.cljs index 826b54241a..ac1a7886c1 100644 --- a/src/quo/components/animated_header.cljs +++ b/src/quo/components/animated_header.cljs @@ -2,10 +2,10 @@ (:require [oops.core :refer [oget]] [quo.animated :as animated] [quo.components.header :as header] - [quo.components.safe-area :as safe-area] [quo.design-system.colors :as colors] [quo.platform :as platform] - [reagent.core :as reagent])) + [reagent.core :as reagent] + [react-native.safe-area :as safe-area])) (defn header-wrapper-style [{:keys [value offset]}] @@ -95,11 +95,9 @@ (defn header [{:keys [use-insets] :as props} & children] (if use-insets - [safe-area/consumer - (fn [insets] - [header-container - (-> props - (dissoc :use-insets) - (assoc :insets insets)) - children])] + [header-container + (-> props + (dissoc :use-insets) + (assoc :insets (safe-area/get-insets))) + children] [header-container props children])) diff --git a/src/quo/components/bottom_sheet/view.cljs b/src/quo/components/bottom_sheet/view.cljs index 624d937dcd..ae6fe501f8 100644 --- a/src/quo/components/bottom_sheet/view.cljs +++ b/src/quo/components/bottom_sheet/view.cljs @@ -2,13 +2,13 @@ (:require [cljs-bean.core :as bean] [quo.animated :as animated] [quo.components.bottom-sheet.style :as styles] - [quo.components.safe-area :as safe-area] [quo.design-system.colors :as colors] [quo.gesture-handler :as gesture-handler] [quo.platform :as platform] [quo.react :as react] [quo.react-native :as rn] - [reagent.core :as reagent])) + [reagent.core :as reagent] + [react-native.safe-area :as safe-area])) (def opacity-coeff 0.8) (def close-duration 150) @@ -43,7 +43,7 @@ (rn/use-keyboard) keyboard-height-android-delta (if (and platform/android? keyboard-shown) (+ keyboard-height 20) 0) - safe-area (safe-area/use-safe-area) + safe-area (safe-area/get-insets) window-height (- window-height (if platform/android? (+ 50 keyboard-height-android-delta) ;; TODO : remove 50 when diff --git a/src/quo/components/safe_area.cljs b/src/quo/components/safe_area.cljs deleted file mode 100644 index 03e808cb87..0000000000 --- a/src/quo/components/safe_area.cljs +++ /dev/null @@ -1,23 +0,0 @@ -(ns quo.components.safe-area - (:require ["react-native-safe-area-context" :as safe-area-context :refer - (SafeAreaView SafeAreaProvider SafeAreaInsetsContext useSafeAreaInsets)] - [reagent.core :as reagent])) - -(def provider (reagent/adapt-react-class SafeAreaProvider)) -(def ^:private consumer-raw (reagent/adapt-react-class (.-Consumer ^js SafeAreaInsetsContext))) -(def view (reagent/adapt-react-class SafeAreaView)) - -(defn consumer - [component] - [consumer-raw - (fn [insets] - (reagent/as-element - [component (js->clj insets :keywordize-keys true)]))]) - -(defn use-safe-area - [] - (let [insets (useSafeAreaInsets)] - {:top (.-top ^js insets) - :bottom (.-bottom ^js insets) - :left (.-left ^js insets) - :right (.-right ^js insets)})) diff --git a/src/quo/core.cljs b/src/quo/core.cljs index 985e0fb1af..0b3eb3d4b7 100644 --- a/src/quo/core.cljs +++ b/src/quo/core.cljs @@ -8,7 +8,6 @@ [quo.components.list.header :as list-header] [quo.components.list.index :as list-index] [quo.components.list.item :as list-item] - [quo.components.safe-area :as safe-area] [quo.components.separator :as separator] [quo.components.text :as text] [quo.components.text-input :as text-input] @@ -29,8 +28,5 @@ (def switch controls/switch) (def radio controls/radio) (def checkbox controls/checkbox) -(def safe-area-provider safe-area/provider) -(def safe-area-consumer safe-area/consumer) -(def safe-area-view safe-area/view) (def separator separator/separator) (def get-color colors/get-color) diff --git a/src/quo2/components/animated_header_flatlist/view.cljs b/src/quo2/components/animated_header_flatlist/view.cljs index 181db763b0..4a82f9d928 100644 --- a/src/quo2/components/animated_header_flatlist/view.cljs +++ b/src/quo2/components/animated_header_flatlist/view.cljs @@ -30,7 +30,7 @@ (reanimated/set-shared-value scroll-y current-y))) (defn header - [{:keys [theme-color display-picture-comp cover-uri title-comp]} top-inset scroll-y] + [{:keys [theme-color f-display-picture-comp cover-uri title-comp]} top-inset scroll-y] (let [input-range [0 (* threshold 0.33)] picture-scale-down 0.4 size-animation (interpolate scroll-y input-range [80 (* 80 picture-scale-down)]) @@ -48,50 +48,49 @@ [reanimated/view {:style (style/header-bottom-part border-animation)} [title-comp]] [reanimated/view {:style (style/entity-picture size-animation)} - [display-picture-comp image-animation]]])) + [:f> f-display-picture-comp image-animation]]])) + +(defn- f-animated-header-list + [{:keys [header-comp main-comp back-button-on-press] :as params}] + (let [window-height (:height (rn/get-window)) + {:keys [top bottom]} (safe-area/get-insets) + ;; view height calculation is different because window height is different on iOS and Android: + view-height (if platform/ios? + (- window-height bottom) + (+ window-height top)) + initial-y (if platform/ios? (- top) 0) + scroll-y (reanimated/use-shared-value initial-y) + opacity-animation (interpolate scroll-y + [(* threshold 0.33) (* threshold 0.66)] + [0 1]) + translate-animation (interpolate scroll-y [(* threshold 0.66) threshold] [100 56]) + title-opacity-animation (interpolate scroll-y [(* threshold 0.66) threshold] [0 1])] + [rn/view {:style (style/container-view view-height)} + [rn/touchable-opacity + {:active-opacity 1 + :on-press back-button-on-press + :style (style/button-container {:left 20})} + [quo/icon :i/arrow-left {:size 20 :color (colors/theme-colors colors/black colors/white)}]] + [rn/touchable-opacity + {:active-opacity 1 + :style (style/button-container {:right 20})} + [quo/icon :i/options {:size 20 :color (colors/theme-colors colors/black colors/white)}]] + [reanimated/blur-view + {:blurAmount 32 + :blurType :light + :overlayColor (if platform/ios? colors/white-opa-70 :transparent) + :style (style/blur-view opacity-animation)} + [reanimated/view {:style (style/header-comp translate-animation title-opacity-animation)} + [header-comp]]] + [reanimated/flat-list + {:data [nil] + :render-fn main-comp + :key-fn str + :header (reagent/as-element (header params top scroll-y)) + ;; TODO: https://github.com/status-im/status-mobile/issues/14924 + :scroll-event-throttle 8 + :on-scroll (fn [event] (scroll-handler event initial-y scroll-y))}]])) (defn animated-header-list - [{:keys [header-comp main-comp back-button-on-press] :as parameters}] - [safe-area/consumer - (fn [insets] - (let [window-height (:height (rn/get-window)) - status-bar-height (rn/status-bar-height) - bottom-inset (:bottom insets) - ;; view height calculation is different because window height is different on iOS and Android: - view-height (if platform/ios? - (- window-height bottom-inset) - (+ window-height status-bar-height)) - initial-y (if platform/ios? (- (:top insets)) 0)] - [:f> - (fn [] - (let [scroll-y (reanimated/use-shared-value initial-y) - opacity-animation (interpolate scroll-y - [(* threshold 0.33) (* threshold 0.66)] - [0 1]) - translate-animation (interpolate scroll-y [(* threshold 0.66) threshold] [100 56]) - title-opacity-animation (interpolate scroll-y [(* threshold 0.66) threshold] [0 1])] - [rn/view {:style (style/container-view view-height)} - [rn/touchable-opacity - {:active-opacity 1 - :on-press back-button-on-press - :style (style/button-container {:left 20})} - [quo/icon :i/arrow-left {:size 20 :color (colors/theme-colors colors/black colors/white)}]] - [rn/touchable-opacity - {:active-opacity 1 - :style (style/button-container {:right 20})} - [quo/icon :i/options {:size 20 :color (colors/theme-colors colors/black colors/white)}]] - [reanimated/blur-view - {:blurAmount 32 - :blurType :light - :overlayColor (if platform/ios? colors/white-opa-70 :transparent) - :style (style/blur-view opacity-animation)} - [reanimated/view {:style (style/header-comp translate-animation title-opacity-animation)} - [header-comp]]] - [reanimated/flat-list - {:data [nil] - :render-fn main-comp - :key-fn str - :header (reagent/as-element (header parameters (:top insets) scroll-y)) - ;; TODO: https://github.com/status-im/status-mobile/issues/14924 - :scroll-event-throttle 8 - :on-scroll (fn [event] (scroll-handler event initial-y scroll-y))}]]))]))]) + [params] + [:f> f-animated-header-list params]) diff --git a/src/quo2/components/code/snippet.cljs b/src/quo2/components/code/snippet.cljs index b203f71f93..632d30e869 100644 --- a/src/quo2/components/code/snippet.cljs +++ b/src/quo2/components/code/snippet.cljs @@ -65,10 +65,10 @@ 18 ;; ~ 9 is char width, 18 is width used in Figma. (* 9 max-line-digits font-scale)))) -(defn- native-renderer +(defn- f-native-renderer [{:keys [rows max-lines on-copy-press] :or {max-lines ##Inf}}] - (let [font-scale (:font-scale (rn/use-window-dimensions)) + (let [font-scale (:font-scale (rn/get-window)) total-rows (count rows) number-rows-to-show (min (count rows) max-lines) line-number-width (calc-line-number-width font-scale number-rows-to-show) @@ -100,7 +100,7 @@ {:language language :renderer (fn [^js/Object props] (reagent/as-element - [:f> native-renderer + [:f> f-native-renderer {:rows (-> props .-rows bean/->clj) :on-copy-press #(when on-copy-press (on-copy-press children)) :max-lines max-lines}])) diff --git a/src/quo2/components/dropdowns/dropdown.cljs b/src/quo2/components/dropdowns/dropdown.cljs index edd6567627..c7364f2cc9 100644 --- a/src/quo2/components/dropdowns/dropdown.cljs +++ b/src/quo2/components/dropdowns/dropdown.cljs @@ -43,7 +43,7 @@ (colors/alpha color 0.6)) (defn dropdown-comp - [{:keys [icon open? dd-height size disabled? dd-color use-border? border-color]}] + [{:keys [icon dd-height size disabled? dd-color use-border? border-color]}] (let [dark? (colors/dark?) {:keys [width height width-with-icon padding font icon-size]} (size sizes) {:keys [padding-with-icon padding-with-no-icon]} padding @@ -51,74 +51,75 @@ spacing (case size :big 4 :medium 2 - :small 2)] - [rn/touchable-opacity - (cond-> - {:on-press (fn [] - (if (swap! open? not) - (apply-anim dd-height 120) - (apply-anim dd-height 0))) - :style (cond-> - (merge - (if icon - padding-with-icon - padding-with-no-icon) - {:width (if icon - width-with-icon - width) - :height height - :border-radius (case size - :big 12 - :medium 10 - :small 8) - :flex-direction :row - :align-items :center - :background-color (if @open? - dd-color - (color-by-10 dd-color))}) - use-border? (assoc :border-width 1 - :border-color (if @open? - border-color - (color-by-10 border-color))))} - disabled? (assoc-in [:style :opacity] 0.3) - disabled? (assoc :disabled true)) - (when icon - [icons/icon icon - {:no-color true - :size 20 - :container-style {:margin-right spacing - :margin-top 1 - :width icon-size - :height icon-size}}]) - [text/text - {:size font-size - :weight :medium - :font :font-medium - :color :main} "Dropdown"] - [icons/icon - (if @open? - (if dark? - :main-icons/pullup-dark - :main-icons/pullup) - (if dark? - :main-icons/dropdown-dark - :main-icons/dropdown)) - {:size 20 - :no-color true - :container-style {:width (+ icon-size 3) - :border-radius 20 - :margin-left (if (= :small size) - 2 - 4) - :margin-top 1 - :height (+ icon-size 4)}}]])) + :small 2) + open? (reagent/atom false)] + (fn [] + [rn/touchable-opacity + (cond-> + {:on-press (fn [] + (if (swap! open? not) + (apply-anim dd-height 120) + (apply-anim dd-height 0))) + :style (cond-> + (merge + (if icon + padding-with-icon + padding-with-no-icon) + {:width (if icon + width-with-icon + width) + :height height + :border-radius (case size + :big 12 + :medium 10 + :small 8) + :flex-direction :row + :align-items :center + :background-color (if @open? + dd-color + (color-by-10 dd-color))}) + use-border? (assoc :border-width 1 + :border-color (if @open? + border-color + (color-by-10 border-color))))} + disabled? (assoc-in [:style :opacity] 0.3) + disabled? (assoc :disabled true)) + (when icon + [icons/icon icon + {:no-color true + :size 20 + :container-style {:margin-right spacing + :margin-top 1 + :width icon-size + :height icon-size}}]) + [text/text + {:size font-size + :weight :medium + :font :font-medium + :color :main} "Dropdown"] + [icons/icon + (if @open? + (if dark? + :main-icons/pullup-dark + :main-icons/pullup) + (if dark? + :main-icons/dropdown-dark + :main-icons/dropdown)) + {:size 20 + :no-color true + :container-style {:width (+ icon-size 3) + :border-radius 20 + :margin-left (if (= :small size) + 2 + 4) + :margin-top 1 + :height (+ icon-size 4)}}]]))) (defn items-comp [{:keys [items on-select]}] (let [items-count (count items)] [rn/scroll-view - {:style {:height "100%"} - :horizontal false + {:horizontal false :nestedScrollEnabled true} (doall (map-indexed (fn [index item] @@ -136,29 +137,29 @@ [text/text {:style {:text-align :center}} item]]) items))])) -(defn dropdown +(defn- f-dropdown [{:keys [items icon text default-item on-select size disabled? border-color use-border? dd-color]}] - [:f> - (fn [] - (let [open? (reagent/atom false) - dd-height (reanimated/use-shared-value 0)] - [rn/view {:style {:flex-grow 1}} - [dropdown-comp - {:items items - :icon icon - :disabled? disabled? - :size size - :dd-color dd-color - :text text - :border-color (colors/custom-color-by-theme border-color 50 60) - :use-border? use-border? - :default-item default-item - :open? open? - :dd-height dd-height}] - [reanimated/view - {:style (reanimated/apply-animations-to-style - {:height dd-height} - {:height dd-height})} - [items-comp - {:items items - :on-select on-select}]]]))]) + (let [dd-height (reanimated/use-shared-value 0)] + [rn/view {:style {:flex-grow 1}} + [dropdown-comp + {:items items + :icon icon + :disabled? disabled? + :size size + :dd-color dd-color + :text text + :border-color (colors/custom-color-by-theme border-color 50 60) + :use-border? use-border? + :default-item default-item + :dd-height dd-height}] + [reanimated/view + {:style (reanimated/apply-animations-to-style + {:height dd-height} + {})} + [items-comp + {:items items + :on-select on-select}]]])) + +(defn dropdown + [params] + [:f> f-dropdown params]) diff --git a/src/quo2/components/links/url_preview_list/view.cljs b/src/quo2/components/links/url_preview_list/view.cljs index f9d4ab589d..f91611ddbd 100644 --- a/src/quo2/components/links/url_preview_list/view.cljs +++ b/src/quo2/components/links/url_preview_list/view.cljs @@ -50,7 +50,7 @@ (- (oops/oget e "nativeEvent.layout.width") (* 2 horizontal-spacing)))) -(defn- view-component +(defn- f-view [] (let [preview-width (reagent/atom 0) flat-list-ref (atom nil)] @@ -83,4 +83,4 @@ (defn view [props] - [:f> view-component props]) + [:f> f-view props]) diff --git a/src/quo2/components/loaders/skeleton.cljs b/src/quo2/components/loaders/skeleton.cljs index 1a8578844c..a7cd5d6218 100644 --- a/src/quo2/components/loaders/skeleton.cljs +++ b/src/quo2/components/loaders/skeleton.cljs @@ -20,61 +20,59 @@ :message 144}]) ;; Standlone message skeleton -(defn message-skeleton +(defn- f-message-skeleton [] - [:f> - (fn [] - (let [color (colors/theme-colors colors/neutral-5 colors/neutral-70) - loading-color (colors/theme-colors colors/neutral-10 colors/neutral-60) - content-width (rand-nth message-content-width) - author-width (content-width :author) - message-width (content-width :message) - {window-width :width} (rn/use-window-dimensions) - translate-x (reanimated/use-shared-value (- window-width)) - animated-gradient-style (reanimated/apply-animations-to-style - {:transform [{:translateX translate-x}]} - {:width window-width - :height "100%"})] - (reanimated/animate-shared-value-with-repeat translate-x window-width 1000 :linear (- 1) false) - [masked-view/masked-view - {:style {:height message-skeleton-height} - :maskElement (reagent/as-element - [rn/view - {:style {:height message-skeleton-height - :flex-direction :row - :padding-vertical 11 - :background-color :transparent - :padding-left 21}} - [rn/view - {:style {:height avatar-skeleton-size - :width avatar-skeleton-size - :border-radius (/ avatar-skeleton-size 2) - :background-color color - :overflow :hidden}}] - [rn/view - {:style {:padding-left 8 - :background-color :transparent}} - [rn/view - {:style {:height 8 - :width author-width - :border-radius 6 - :background-color color - :margin-bottom 8 - :overflow :hidden}}] - [rn/view - {:style {:height 16 - :width message-width - :border-radius 6 - :overflow :hidden - :background-color color}}]]])} - [rn/view - {:style {:flex 1 - :background-color color}} - [reanimated/linear-gradient - {:colors [color color loading-color color color] - :start {:x 0 :y 0} - :end {:x 1 :y 0} - :style animated-gradient-style}]]]))]) + (let [color (colors/theme-colors colors/neutral-5 colors/neutral-70) + loading-color (colors/theme-colors colors/neutral-10 colors/neutral-60) + content-width (rand-nth message-content-width) + author-width (content-width :author) + message-width (content-width :message) + {window-width :width} (rn/get-window) + translate-x (reanimated/use-shared-value (- window-width)) + animated-gradient-style (reanimated/apply-animations-to-style + {:transform [{:translateX translate-x}]} + {:width window-width + :height "100%"})] + (reanimated/animate-shared-value-with-repeat translate-x window-width 1000 :linear (- 1) false) + [masked-view/masked-view + {:style {:height message-skeleton-height} + :maskElement (reagent/as-element + [rn/view + {:style {:height message-skeleton-height + :flex-direction :row + :padding-vertical 11 + :background-color :transparent + :padding-left 21}} + [rn/view + {:style {:height avatar-skeleton-size + :width avatar-skeleton-size + :border-radius (/ avatar-skeleton-size 2) + :background-color color + :overflow :hidden}}] + [rn/view + {:style {:padding-left 8 + :background-color :transparent}} + [rn/view + {:style {:height 8 + :width author-width + :border-radius 6 + :background-color color + :margin-bottom 8 + :overflow :hidden}}] + [rn/view + {:style {:height 16 + :width message-width + :border-radius 6 + :overflow :hidden + :background-color color}}]]])} + [rn/view + {:style {:flex 1 + :background-color color}} + [reanimated/linear-gradient + {:colors [color color loading-color color color] + :start {:x 0 :y 0} + :end {:x 1 :y 0} + :style animated-gradient-style}]]])) (defn skeleton [parent-height] @@ -84,5 +82,6 @@ colors/white colors/neutral-90) :flex 1}} - (for [n (range number-of-skeletons)] - [message-skeleton {:key n}])])) + (doall + (for [n (range number-of-skeletons)] + [:f> f-message-skeleton {:key n}]))])) diff --git a/src/quo2/components/messages/author/view.cljs b/src/quo2/components/messages/author/view.cljs index 6ad0e1d7ea..04cd6ab962 100644 --- a/src/quo2/components/messages/author/view.cljs +++ b/src/quo2/components/messages/author/view.cljs @@ -10,64 +10,62 @@ (defn author [{:keys [primary-name secondary-name short-chat-key time-str contact? verified? untrustworthy?]}] - [:f> - (fn [] - [rn/view {:style style/container} + [rn/view {:style style/container} + [:<> + [text/text + {:weight :semi-bold + :size :paragraph-2 + :number-of-lines 1 + :style {:color (colors/theme-colors colors/neutral-100 colors/white)}} + primary-name] + (when (not (string/blank? secondary-name)) [:<> [text/text - {:weight :semi-bold + {:size :paragraph-2 + :number-of-lines 1 + :style style/middle-dot-nickname} + middle-dot] + [text/text + {:weight :medium :size :paragraph-2 :number-of-lines 1 - :style {:color (colors/theme-colors colors/neutral-100 colors/white)}} - primary-name] - (when (not (string/blank? secondary-name)) - [:<> - [text/text - {:size :paragraph-2 - :number-of-lines 1 - :style style/middle-dot-nickname} - middle-dot] - [text/text - {:weight :medium - :size :paragraph-2 - :number-of-lines 1 - :style {:color (colors/theme-colors colors/neutral-60 colors/neutral-40)}} - secondary-name]])] - (when contact? - [icons/icon :main-icons2/contact - {:size 12 - :no-color true - :container-style style/icon-container}]) - (cond - verified? - [icons/icon :main-icons2/verified - {:size 12 - :no-color true - :container-style style/icon-container}] - untrustworthy? - [icons/icon :main-icons2/untrustworthy - {:size 12 - :no-color true - :container-style style/icon-container}]) - (when (and (not verified?) short-chat-key) - [text/text - {:monospace true - :size :paragraph-2 - :number-of-lines 1 - :style style/chat-key-text} - short-chat-key]) - (when (and (not verified?) time-str) - [text/text - {:monospace true - :size :paragraph-2 - :number-of-lines 1 - :style style/middle-dot-chat-key} - middle-dot]) - (when time-str - [text/text - {:monospace true - :size :paragraph-2 - :accessibility-label :message-timestamp - :number-of-lines 1 - :style (style/time-text verified?)} - time-str])])]) + :style {:color (colors/theme-colors colors/neutral-60 colors/neutral-40)}} + secondary-name]])] + (when contact? + [icons/icon :main-icons2/contact + {:size 12 + :no-color true + :container-style style/icon-container}]) + (cond + verified? + [icons/icon :main-icons2/verified + {:size 12 + :no-color true + :container-style style/icon-container}] + untrustworthy? + [icons/icon :main-icons2/untrustworthy + {:size 12 + :no-color true + :container-style style/icon-container}]) + (when (and (not verified?) short-chat-key) + [text/text + {:monospace true + :size :paragraph-2 + :number-of-lines 1 + :style style/chat-key-text} + short-chat-key]) + (when (and (not verified?) time-str) + [text/text + {:monospace true + :size :paragraph-2 + :number-of-lines 1 + :style style/middle-dot-chat-key} + middle-dot]) + (when time-str + [text/text + {:monospace true + :size :paragraph-2 + :accessibility-label :message-timestamp + :number-of-lines 1 + :style (style/time-text verified?)} + time-str])]) diff --git a/src/quo2/components/messages/system_message.cljs b/src/quo2/components/messages/system_message.cljs index 9900f3e05a..32f9b99bec 100644 --- a/src/quo2/components/messages/system_message.cljs +++ b/src/quo2/components/messages/system_message.cljs @@ -172,31 +172,33 @@ :style {:color (get-color :time)}} (utils/truncate-str (:info content) 24)])]]]]) -(defn system-message +(defn- f-system-message [{:keys [type style non-pressable? animate-landing? labels on-long-press] :as message}] - [:f> - (fn [] - (let [sv-color (reanimated/use-shared-value - (get-color :bg (if animate-landing? :landed :default) type))] - (when animate-landing? - (reanimated/animate-shared-value-with-delay - sv-color - (get-color :bg :default type) - 0 - :linear - 1000)) - [reanimated/touchable-opacity - {:on-press #(when-not non-pressable? - (reanimated/set-shared-value sv-color (get-color :bg :pressed type))) - :on-long-press on-long-press - :style (reanimated/apply-animations-to-style - {:background-color sv-color} - (merge - {:flex-direction :row - :flex 1 - :border-radius 16 - :padding-vertical 9 - :padding-horizontal 11 - :background-color sv-color} - style))} - [sm-render message labels]]))]) + (let [sv-color (reanimated/use-shared-value + (get-color :bg (if animate-landing? :landed :default) type))] + (when animate-landing? + (reanimated/animate-shared-value-with-delay + sv-color + (get-color :bg :default type) + 0 + :linear + 1000)) + [reanimated/touchable-opacity + {:on-press #(when-not non-pressable? + (reanimated/set-shared-value sv-color (get-color :bg :pressed type))) + :on-long-press on-long-press + :style (reanimated/apply-animations-to-style + {:background-color sv-color} + (merge + {:flex-direction :row + :flex 1 + :border-radius 16 + :padding-vertical 9 + :padding-horizontal 11 + :background-color sv-color} + style))} + [sm-render message labels]])) + +(defn system-message + [message] + [:f> f-system-message message]) diff --git a/src/quo2/components/navigation/bottom_nav_tab.cljs b/src/quo2/components/navigation/bottom_nav_tab.cljs index 0f5390581d..a5b3894117 100644 --- a/src/quo2/components/navigation/bottom_nav_tab.cljs +++ b/src/quo2/components/navigation/bottom_nav_tab.cljs @@ -16,7 +16,7 @@ pass-through? colors/white-opa-5 :else colors/neutral-70))) -(defn bottom-nav-tab +(defn- f-bottom-nav-tab "[bottom-nav-tab opts] opts {:icon :i/communities @@ -29,66 +29,68 @@ " [{:keys [icon new-notifications? notification-indicator counter-label on-press pass-through? icon-color-anim accessibility-label test-ID]}] - [:f> - (fn [] - (let [icon-animated-style (reanimated/apply-animations-to-style - {:tint-color icon-color-anim} - {:width 24 - :height 24 - :margin-left 33 - :margin-top 8}) - background-color (reanimated/use-shared-value "transparent") - background-animated-style (reanimated/apply-animations-to-style - {:background-color background-color} - {:width 90 - :height 40 - :border-radius 10})] - [rn/touchable-without-feedback - {:test-ID test-ID - :on-press on-press - :on-press-in #(toggle-background-color background-color false pass-through?) - :on-press-out #(toggle-background-color background-color true pass-through?) - :accessibility-label accessibility-label} - [reanimated/view {:style background-animated-style} - ;; In android animations are not working for the animated components which are nested by - ;; hole-view, - ;; Interestingly this only happens when hole view and blur view are used together - ;; Similar behavior is also seen while removing holes, and to fix that we used key and - ;; force-rendered view - ;; But we need animations faster for tab clicks, so we can't rely on reagent atoms, - ;; so for now only using hole view for the ios tab icon notification boundary - (if platform/ios? - [hole-view/hole-view - {:key new-notifications? ;; Key is required to force removal of holes - :holes (cond - (not new-notifications?) ;; No new notifications, remove holes - [] + (let [icon-animated-style (reanimated/apply-animations-to-style + {:tint-color icon-color-anim} + {:width 24 + :height 24 + :margin-left 33 + :margin-top 8}) + background-color (reanimated/use-shared-value "transparent") + background-animated-style (reanimated/apply-animations-to-style + {:background-color background-color} + {:width 90 + :height 40 + :border-radius 10})] + [rn/touchable-without-feedback + {:test-ID test-ID + :on-press on-press + :on-press-in #(toggle-background-color background-color false pass-through?) + :on-press-out #(toggle-background-color background-color true pass-through?) + :accessibility-label accessibility-label} + [reanimated/view {:style background-animated-style} + ;; In android animations are not working for the animated components which are nested by + ;; hole-view, + ;; Interestingly this only happens when hole view and blur view are used together + ;; Similar behavior is also seen while removing holes, and to fix that we used key and + ;; force-rendered view + ;; But we need animations faster for tab clicks, so we can't rely on reagent atoms, + ;; so for now only using hole view for the ios tab icon notification boundary + (if platform/ios? + [hole-view/hole-view + {:key new-notifications? ;; Key is required to force removal of holes + :holes (cond + (not new-notifications?) ;; No new notifications, remove holes + [] - (= notification-indicator :unread-dot) - [{:x 50 :y 5 :width 10 :height 10 :borderRadius 5}] + (= notification-indicator :unread-dot) + [{:x 50 :y 5 :width 10 :height 10 :borderRadius 5}] - :else - [{:x 47 :y 1 :width 18 :height 18 :borderRadius 7}])} - [reanimated/image - {:style icon-animated-style - :source (icons/icon-source (keyword (str icon 24)))}]] - [reanimated/image - {:style icon-animated-style - :source (icons/icon-source (keyword (str icon 24)))}]) - (when new-notifications? - (if (= notification-indicator :counter) - [counter/counter - {:override-text-color colors/white - :override-bg-color colors/primary-50 - :style {:position :absolute - :left 48 - :top 2}} - counter-label] - [rn/view - {:style {:width 8 - :height 8 - :border-radius 4 - :top 6 - :left 51 - :position :absolute - :background-color colors/primary-50}}]))]]))]) + :else + [{:x 47 :y 1 :width 18 :height 18 :borderRadius 7}])} + [reanimated/image + {:style icon-animated-style + :source (icons/icon-source (keyword (str icon 24)))}]] + [reanimated/image + {:style icon-animated-style + :source (icons/icon-source (keyword (str icon 24)))}]) + (when new-notifications? + (if (= notification-indicator :counter) + [counter/counter + {:override-text-color colors/white + :override-bg-color colors/primary-50 + :style {:position :absolute + :left 48 + :top 2}} + counter-label] + [rn/view + {:style {:width 8 + :height 8 + :border-radius 4 + :top 6 + :left 51 + :position :absolute + :background-color colors/primary-50}}]))]])) + +(defn bottom-nav-tab + [opts] + [:f> f-bottom-nav-tab opts]) diff --git a/src/quo2/components/navigation/floating_shell_button.cljs b/src/quo2/components/navigation/floating_shell_button.cljs index 64149f28e3..fbbf065c58 100644 --- a/src/quo2/components/navigation/floating_shell_button.cljs +++ b/src/quo2/components/navigation/floating_shell_button.cljs @@ -14,40 +14,42 @@ :style style :customization-color customization-color}])) +(defn- f-floating-shell-button + [dynamic-buttons style opacity-anim] + (let [original-style (merge {:flex-direction :row + :margin-horizontal 12 + :pointer-events :box-none} + style) + animated-style (reanimated/apply-animations-to-style + (if opacity-anim + {:opacity opacity-anim} + {}) + original-style)] + [reanimated/view {:style animated-style} + ;; Left Section + [rn/view {:style {:flex 1}} + [dynamic-button-view :search dynamic-buttons + {:position :absolute + :right 8}]] + ;; Mid Section (jump-to) + [dynamic-button-view :jump-to dynamic-buttons nil] + ;; Right Section + [rn/view {:style {:flex 1}} + [rn/view + {:style {:position :absolute + :flex-direction :row + :right 0}} + [dynamic-button-view :mention dynamic-buttons {:margin-left 8}] + [dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}] + [dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}] + [dynamic-button-view :scroll-to-bottom dynamic-buttons {:margin-left 8}]]]])) + (defn floating-shell-button "[floating-shell-button dynamic-buttons style opacity-anim pointer-anim] dynamic-buttons {:button-type {:on-press on-press :count count}} style override style opacity-anim reanimated value (optional)" - ([dynamic-button style] - (floating-shell-button dynamic-button style nil)) + ([dynamic-buttons style] + [:f> f-floating-shell-button dynamic-buttons style nil]) ([dynamic-buttons style opacity-anim] - [:f> - (fn [] - (let [original-style (merge {:flex-direction :row - :margin-horizontal 12 - :pointer-events :box-none} - style) - animated-style (reanimated/apply-animations-to-style - (if opacity-anim - {:opacity opacity-anim} - {}) - original-style)] - [reanimated/view {:style animated-style} - ;; Left Section - [rn/view {:style {:flex 1}} - [dynamic-button-view :search dynamic-buttons - {:position :absolute - :right 8}]] - ;; Mid Section (jump-to) - [dynamic-button-view :jump-to dynamic-buttons nil] - ;; Right Section - [rn/view {:style {:flex 1}} - [rn/view - {:style {:position :absolute - :flex-direction :row - :right 0}} - [dynamic-button-view :mention dynamic-buttons {:margin-left 8}] - [dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}] - [dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}] - [dynamic-button-view :scroll-to-bottom dynamic-buttons {:margin-left 8}]]]]))])) + [:f> f-floating-shell-button dynamic-buttons style opacity-anim])) diff --git a/src/quo2/components/profile/profile_card/view.cljs b/src/quo2/components/profile/profile_card/view.cljs index 6151609b50..c58acb0f37 100644 --- a/src/quo2/components/profile/profile_card/view.cljs +++ b/src/quo2/components/profile/profile_card/view.cljs @@ -10,7 +10,7 @@ [quo2.components.profile.profile-card.style :as style] [quo2.components.avatars.user-avatar.view :as user-avatar])) -(defn- profile-card-component +(defn- f-profile-card-component [{:keys [keycard-account? profile-picture name hash customization-color emoji-hash on-options-press show-emoji-hash? show-options-button? show-user-hash? @@ -25,7 +25,7 @@ last-item? false card-style {:padding-horizontal 20 :flex 1}}}] - (let [{:keys [width]} (rn/use-window-dimensions) + (let [{:keys [width]} (rn/get-window) padding-bottom (cond login-card? 38 show-emoji-hash? 12 @@ -104,4 +104,4 @@ (defn profile-card [props] - [:f> profile-card-component props]) + [:f> f-profile-card-component props]) diff --git a/src/quo2/components/record_audio/record_audio/buttons/delete_button.cljs b/src/quo2/components/record_audio/record_audio/buttons/delete_button.cljs index 53e1db92d9..36fdcf8b0d 100644 --- a/src/quo2/components/record_audio/record_audio/buttons/delete_button.cljs +++ b/src/quo2/components/record_audio/record_audio/buttons/delete_button.cljs @@ -6,85 +6,83 @@ [react-native.core :refer [use-effect]] [quo2.components.record-audio.record-audio.helpers :as helpers])) -(defn delete-button +(defn f-delete-button [recording? ready-to-delete? reviewing-audio? force-show-controls?] - [:f> - (fn [] - (let [opacity (reanimated/use-shared-value (if force-show-controls? 1 0)) - translate-x (reanimated/use-shared-value (if force-show-controls? 35 20)) - scale (reanimated/use-shared-value (if force-show-controls? 0.75 1)) - connector-opacity (reanimated/use-shared-value 0) - connector-width (reanimated/use-shared-value 24) - connector-height (reanimated/use-shared-value 12) - border-radius-first-half (reanimated/use-shared-value 8) - border-radius-second-half (reanimated/use-shared-value 8) - start-x-animation (fn [] - (helpers/animate-linear-with-delay translate-x 12 50 133.33) - (helpers/animate-easing-with-delay connector-opacity 1 0 93.33) - (helpers/animate-easing-with-delay connector-width 56 83.33 80) - (helpers/animate-easing-with-delay connector-height 56 83.33 80) - (helpers/animate-easing-with-delay border-radius-first-half - 28 - 83.33 - 80) - (helpers/animate-easing-with-delay border-radius-second-half - 28 - 83.33 - 80)) - reset-x-animation (fn [] - (helpers/animate-linear translate-x 0 100) - (helpers/set-value connector-opacity 0) - (helpers/set-value connector-width 24) - (helpers/set-value connector-height 12) - (helpers/set-value border-radius-first-half 8) - (helpers/set-value border-radius-second-half 16)) - fade-in-animation (fn [] - (helpers/animate-linear translate-x 0 200) - (helpers/animate-linear opacity 1 200)) - fade-out-animation (fn [] - (helpers/animate-linear - translate-x - (if @reviewing-audio? 35 20) - 200) - (if @reviewing-audio? - (helpers/animate-linear scale 0.75 200) - (helpers/animate-linear opacity 0 200)) - (helpers/set-value connector-opacity 0) - (helpers/set-value connector-width 24) - (helpers/set-value connector-height 12) - (helpers/set-value border-radius-first-half 8) - (helpers/set-value border-radius-second-half 16)) - fade-out-reset-animation (fn [] - (helpers/animate-linear opacity 0 200) - (helpers/animate-linear-with-delay translate-x 20 0 200) - (helpers/animate-linear-with-delay scale 1 0 200))] - (use-effect (fn [] - (if @recording? - (fade-in-animation) - (fade-out-animation))) - [@recording?]) - (use-effect (fn [] - (when-not @reviewing-audio? - (fade-out-reset-animation))) - [@reviewing-audio?]) - (use-effect (fn [] - (cond - @ready-to-delete? - (start-x-animation) - @recording? - (reset-x-animation))) - [@ready-to-delete?]) - [:<> - [reanimated/view {:style (style/delete-button-container opacity)} - [reanimated/view - {:style (style/delete-button-connector connector-opacity - connector-width - connector-height - border-radius-first-half - border-radius-second-half)}]] - [reanimated/view - {:style (style/delete-button scale translate-x opacity) - :pointer-events :none} - [icons/icon :i/delete - {:color colors/white - :size 20}]]]))]) + (let [opacity (reanimated/use-shared-value (if force-show-controls? 1 0)) + translate-x (reanimated/use-shared-value (if force-show-controls? 35 20)) + scale (reanimated/use-shared-value (if force-show-controls? 0.75 1)) + connector-opacity (reanimated/use-shared-value 0) + connector-width (reanimated/use-shared-value 24) + connector-height (reanimated/use-shared-value 12) + border-radius-first-half (reanimated/use-shared-value 8) + border-radius-second-half (reanimated/use-shared-value 8) + start-x-animation (fn [] + (helpers/animate-linear-with-delay translate-x 12 50 133.33) + (helpers/animate-easing-with-delay connector-opacity 1 0 93.33) + (helpers/animate-easing-with-delay connector-width 56 83.33 80) + (helpers/animate-easing-with-delay connector-height 56 83.33 80) + (helpers/animate-easing-with-delay border-radius-first-half + 28 + 83.33 + 80) + (helpers/animate-easing-with-delay border-radius-second-half + 28 + 83.33 + 80)) + reset-x-animation (fn [] + (helpers/animate-linear translate-x 0 100) + (helpers/set-value connector-opacity 0) + (helpers/set-value connector-width 24) + (helpers/set-value connector-height 12) + (helpers/set-value border-radius-first-half 8) + (helpers/set-value border-radius-second-half 16)) + fade-in-animation (fn [] + (helpers/animate-linear translate-x 0 200) + (helpers/animate-linear opacity 1 200)) + fade-out-animation (fn [] + (helpers/animate-linear + translate-x + (if @reviewing-audio? 35 20) + 200) + (if @reviewing-audio? + (helpers/animate-linear scale 0.75 200) + (helpers/animate-linear opacity 0 200)) + (helpers/set-value connector-opacity 0) + (helpers/set-value connector-width 24) + (helpers/set-value connector-height 12) + (helpers/set-value border-radius-first-half 8) + (helpers/set-value border-radius-second-half 16)) + fade-out-reset-animation (fn [] + (helpers/animate-linear opacity 0 200) + (helpers/animate-linear-with-delay translate-x 20 0 200) + (helpers/animate-linear-with-delay scale 1 0 200))] + (use-effect (fn [] + (if @recording? + (fade-in-animation) + (fade-out-animation))) + [@recording?]) + (use-effect (fn [] + (when-not @reviewing-audio? + (fade-out-reset-animation))) + [@reviewing-audio?]) + (use-effect (fn [] + (cond + @ready-to-delete? + (start-x-animation) + @recording? + (reset-x-animation))) + [@ready-to-delete?]) + [:<> + [reanimated/view {:style (style/delete-button-container opacity)} + [reanimated/view + {:style (style/delete-button-connector connector-opacity + connector-width + connector-height + border-radius-first-half + border-radius-second-half)}]] + [reanimated/view + {:style (style/delete-button scale translate-x opacity) + :pointer-events :none} + [icons/icon :i/delete + {:color colors/white + :size 20}]]])) diff --git a/src/quo2/components/record_audio/record_audio/buttons/lock_button.cljs b/src/quo2/components/record_audio/record_audio/buttons/lock_button.cljs index dc71fe1302..c65754cc52 100644 --- a/src/quo2/components/record_audio/record_audio/buttons/lock_button.cljs +++ b/src/quo2/components/record_audio/record_audio/buttons/lock_button.cljs @@ -6,76 +6,74 @@ [react-native.core :refer [use-effect]] [quo2.components.record-audio.record-audio.helpers :as helpers])) -(defn lock-button +(defn f-lock-button [recording? ready-to-lock? locked?] - [:f> - (fn [] - (let [translate-x-y (reanimated/use-shared-value 20) - opacity (reanimated/use-shared-value 0) - connector-opacity (reanimated/use-shared-value 0) - width (reanimated/use-shared-value 24) - height (reanimated/use-shared-value 12) - border-radius-first-half (reanimated/use-shared-value 8) - border-radius-second-half (reanimated/use-shared-value 8) - start-x-y-animation (fn [] - (helpers/animate-linear-with-delay translate-x-y 8 50 116.66) - (helpers/animate-easing-with-delay connector-opacity 1 0 80) - (helpers/animate-easing-with-delay width 56 83.33 63.33) - (helpers/animate-easing-with-delay height 56 83.33 63.33) - (helpers/animate-easing-with-delay border-radius-first-half - 28 - 83.33 - 63.33) - (helpers/animate-easing-with-delay border-radius-second-half - 28 - 83.33 - 63.33)) - reset-x-y-animation (fn [] - (helpers/animate-linear translate-x-y 0 100) - (helpers/set-value connector-opacity 0) - (helpers/set-value width 24) - (helpers/set-value height 12) - (helpers/set-value border-radius-first-half 8) - (helpers/set-value border-radius-second-half 16)) - fade-in-animation (fn [] - (helpers/animate-linear translate-x-y 0 220) - (helpers/animate-linear opacity 1 220)) - fade-out-animation (fn [] - (helpers/animate-linear translate-x-y 20 200) - (helpers/animate-linear opacity 0 200) - (helpers/set-value connector-opacity 0) - (helpers/set-value width 24) - (helpers/set-value height 12) - (helpers/set-value border-radius-first-half 8) - (helpers/set-value border-radius-second-half 16))] - (use-effect (fn [] - (if @recording? - (fade-in-animation) - (fade-out-animation))) - [@recording?]) - (use-effect (fn [] - (cond - @ready-to-lock? - (start-x-y-animation) - (and @recording? (not @locked?)) - (reset-x-y-animation))) - [@ready-to-lock?]) - (use-effect (fn [] - (if @locked? - (fade-out-animation) - (reset-x-y-animation))) - [@locked?]) - [:<> - [reanimated/view {:style (style/lock-button-container opacity)} - [reanimated/view - {:style (style/lock-button-connector connector-opacity - width - height - border-radius-first-half - border-radius-second-half)}]] - [reanimated/view - {:style (style/lock-button translate-x-y opacity) - :pointer-events :none} - [icons/icon (if @ready-to-lock? :i/locked :i/unlocked) - {:color (colors/theme-colors colors/black colors/white) - :size 20}]]]))]) + (let [translate-x-y (reanimated/use-shared-value 20) + opacity (reanimated/use-shared-value 0) + connector-opacity (reanimated/use-shared-value 0) + width (reanimated/use-shared-value 24) + height (reanimated/use-shared-value 12) + border-radius-first-half (reanimated/use-shared-value 8) + border-radius-second-half (reanimated/use-shared-value 8) + start-x-y-animation (fn [] + (helpers/animate-linear-with-delay translate-x-y 8 50 116.66) + (helpers/animate-easing-with-delay connector-opacity 1 0 80) + (helpers/animate-easing-with-delay width 56 83.33 63.33) + (helpers/animate-easing-with-delay height 56 83.33 63.33) + (helpers/animate-easing-with-delay border-radius-first-half + 28 + 83.33 + 63.33) + (helpers/animate-easing-with-delay border-radius-second-half + 28 + 83.33 + 63.33)) + reset-x-y-animation (fn [] + (helpers/animate-linear translate-x-y 0 100) + (helpers/set-value connector-opacity 0) + (helpers/set-value width 24) + (helpers/set-value height 12) + (helpers/set-value border-radius-first-half 8) + (helpers/set-value border-radius-second-half 16)) + fade-in-animation (fn [] + (helpers/animate-linear translate-x-y 0 220) + (helpers/animate-linear opacity 1 220)) + fade-out-animation (fn [] + (helpers/animate-linear translate-x-y 20 200) + (helpers/animate-linear opacity 0 200) + (helpers/set-value connector-opacity 0) + (helpers/set-value width 24) + (helpers/set-value height 12) + (helpers/set-value border-radius-first-half 8) + (helpers/set-value border-radius-second-half 16))] + (use-effect (fn [] + (if @recording? + (fade-in-animation) + (fade-out-animation))) + [@recording?]) + (use-effect (fn [] + (cond + @ready-to-lock? + (start-x-y-animation) + (and @recording? (not @locked?)) + (reset-x-y-animation))) + [@ready-to-lock?]) + (use-effect (fn [] + (if @locked? + (fade-out-animation) + (reset-x-y-animation))) + [@locked?]) + [:<> + [reanimated/view {:style (style/lock-button-container opacity)} + [reanimated/view + {:style (style/lock-button-connector connector-opacity + width + height + border-radius-first-half + border-radius-second-half)}]] + [reanimated/view + {:style (style/lock-button translate-x-y opacity) + :pointer-events :none} + [icons/icon (if @ready-to-lock? :i/locked :i/unlocked) + {:color (colors/theme-colors colors/black colors/white) + :size 20}]]])) diff --git a/src/quo2/components/record_audio/record_audio/buttons/record_button.cljs b/src/quo2/components/record_audio/record_audio/buttons/record_button.cljs index bda6755486..fec8c25642 100644 --- a/src/quo2/components/record_audio/record_audio/buttons/record_button.cljs +++ b/src/quo2/components/record_audio/record_audio/buttons/record_button.cljs @@ -7,22 +7,20 @@ [quo2.components.buttons.button :as button] [quo2.components.record-audio.record-audio.helpers :as helpers])) -(defn record-button +(defn f-record-button [recording? reviewing-audio?] - [:f> - (fn [] - (let [opacity (reanimated/use-shared-value 1) - show-animation #(helpers/set-value opacity 1) - hide-animation #(helpers/set-value opacity 0)] - (use-effect (fn [] - (if (or @recording? @reviewing-audio?) - (hide-animation) - (show-animation))) - [@recording? @reviewing-audio?]) - [reanimated/view {:style (style/record-button-container opacity)} - [button/button - {:type :outline - :size 32 - :width 32 - :accessibility-label :mic-button} - [icons/icon :i/audio {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]]]))]) + (let [opacity (reanimated/use-shared-value 1) + show-animation #(helpers/set-value opacity 1) + hide-animation #(helpers/set-value opacity 0)] + (use-effect (fn [] + (if (or @recording? @reviewing-audio?) + (hide-animation) + (show-animation))) + [@recording? @reviewing-audio?]) + [reanimated/view {:style (style/record-button-container opacity)} + [button/button + {:type :outline + :size 32 + :width 32 + :accessibility-label :mic-button} + [icons/icon :i/audio {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]]])) diff --git a/src/quo2/components/record_audio/record_audio/buttons/record_button_big.cljs b/src/quo2/components/record_audio/record_audio/buttons/record_button_big.cljs index 6f6244e6c5..bc2ff7746a 100644 --- a/src/quo2/components/record_audio/record_audio/buttons/record_button_big.cljs +++ b/src/quo2/components/record_audio/record_audio/buttons/record_button_big.cljs @@ -27,177 +27,175 @@ (reagent/as-element [reanimated/view {:style (style/animated-circle scale opacity color)}])))))) -(defn record-button-big +(defn f-record-button-big [recording? ready-to-send? ready-to-lock? ready-to-delete? record-button-is-animating? record-button-at-initial-position? locked? reviewing-audio? recording-timer recording-length-ms clear-timeout touch-active? recorder-ref reload-recorder-fn idle? on-send on-cancel] - [:f> - (fn [] - (let [scale (reanimated/use-shared-value 1) - opacity (reanimated/use-shared-value 0) - opacity-from (if @ready-to-lock? opacity-from-lock opacity-from-default) - animations (map - (fn [index] - (let [ring-scale (worklets.record-audio/ring-scale scale - (* scale-padding - index))] - {:scale ring-scale - :opacity (reanimated/interpolate ring-scale - [1 scale-to-each] - [opacity-from 0])})) - (range 0 5)) - rings-color (cond - @ready-to-lock? (colors/theme-colors colors/neutral-80-opa-5-opaque - colors/neutral-80) - @ready-to-delete? colors/danger-50 - :else colors/primary-50) - translate-y (reanimated/use-shared-value 0) - translate-x (reanimated/use-shared-value 0) - button-color colors/primary-50 - icon-color (if (and (not (colors/dark?)) @ready-to-lock?) colors/black colors/white) - icon-opacity (reanimated/use-shared-value 1) - red-overlay-opacity (reanimated/use-shared-value 0) - gray-overlay-opacity (reanimated/use-shared-value 0) - complete-animation - (fn [] - (cond - (and @ready-to-lock? (not @record-button-is-animating?)) - (do - (reset! locked? true) - (reset! ready-to-lock? false)) - (and (not @locked?) (not @reviewing-audio?)) - (audio/stop-recording - @recorder-ref - (fn [] + (let [scale (reanimated/use-shared-value 1) + opacity (reanimated/use-shared-value 0) + opacity-from (if @ready-to-lock? opacity-from-lock opacity-from-default) + animations (map + (fn [index] + (let [ring-scale (worklets.record-audio/ring-scale scale + (* scale-padding + index))] + {:scale ring-scale + :opacity (reanimated/interpolate ring-scale + [1 scale-to-each] + [opacity-from 0])})) + (range 0 5)) + rings-color (cond + @ready-to-lock? (colors/theme-colors colors/neutral-80-opa-5-opaque + colors/neutral-80) + @ready-to-delete? colors/danger-50 + :else colors/primary-50) + translate-y (reanimated/use-shared-value 0) + translate-x (reanimated/use-shared-value 0) + button-color colors/primary-50 + icon-color (if (and (not (colors/dark?)) @ready-to-lock?) colors/black colors/white) + icon-opacity (reanimated/use-shared-value 1) + red-overlay-opacity (reanimated/use-shared-value 0) + gray-overlay-opacity (reanimated/use-shared-value 0) + complete-animation + (fn [] + (cond + (and @ready-to-lock? (not @record-button-is-animating?)) + (do + (reset! locked? true) + (reset! ready-to-lock? false)) + (and (not @locked?) (not @reviewing-audio?)) + (audio/stop-recording + @recorder-ref + (fn [] + (cond + @ready-to-send? + (when on-send + (on-send {:file-path (audio/get-recorder-file-path @recorder-ref) + :duration @recording-length-ms})) + @ready-to-delete? + (when on-cancel + (on-cancel))) + (reload-recorder-fn) + (reset! recording? false) + (reset! ready-to-send? false) + (reset! ready-to-delete? false) + (reset! ready-to-lock? false) + (reset! idle? true) + (js/setTimeout #(reset! idle? false) 1000) + (js/clearInterval @recording-timer) + (reset! recording-length-ms 0) + (log/debug "[record-audio] stop recording - success")) + #(log/error "[record-audio] stop recording - error: " %)))) + start-animation (fn [] + (helpers/set-value opacity 1) + (helpers/animate-linear scale 2.6 signal-anim-duration) + ;; TODO: Research if we can implement this with withSequence method + ;; from Reanimated 2 + ;; GitHub issue [#14561]: + ;; https://github.com/status-im/status-mobile/issues/14561 + (reset! clear-timeout + (js/setTimeout + (fn [] + (helpers/set-value scale scale-to-each) + (helpers/animate-linear-with-delay-loop scale + scale-to-total + signal-anim-duration-2 + 0)) + signal-anim-duration))) + stop-animation (fn [] + (helpers/set-value opacity 0) + (reanimated/cancel-animation scale) + (helpers/set-value scale 1) + (when @clear-timeout (js/clearTimeout @clear-timeout))) + start-y-animation (fn [] + (reset! record-button-at-initial-position? false) + (reset! record-button-is-animating? true) + (helpers/animate-easing translate-y -64 250) + (helpers/animate-linear-with-delay icon-opacity 0 33.33 76.66) + (js/setTimeout (fn [] + (reset! record-button-is-animating? false) + (when-not @touch-active? (complete-animation))) + 250)) + reset-y-animation (fn [] + (helpers/animate-easing translate-y 0 300) + (helpers/animate-linear icon-opacity 1 500) + (js/setTimeout (fn [] + (reset! record-button-at-initial-position? true)) + 500)) + start-x-animation (fn [] + (reset! record-button-at-initial-position? false) + (reset! record-button-is-animating? true) + (helpers/animate-easing translate-x -64 250) + (helpers/animate-linear-with-delay icon-opacity 0 33.33 76.66) + (helpers/animate-linear red-overlay-opacity 1 33.33) + (js/setTimeout (fn [] + (reset! record-button-is-animating? false) + (when-not @touch-active? (complete-animation))) + 250)) + reset-x-animation (fn [] + (helpers/animate-easing translate-x 0 300) + (helpers/animate-linear icon-opacity 1 500) + (helpers/animate-linear red-overlay-opacity 0 100) + (js/setTimeout (fn [] + (reset! record-button-at-initial-position? true)) + 500)) + start-x-y-animation (fn [] + (reset! record-button-at-initial-position? false) + (reset! record-button-is-animating? true) + (helpers/animate-easing translate-y -44 200) + (helpers/animate-easing translate-x -44 200) + (helpers/animate-linear-with-delay icon-opacity 0 33.33 33.33) + (helpers/animate-linear gray-overlay-opacity 1 33.33) + (js/setTimeout (fn [] + (reset! record-button-is-animating? false) + (when-not @touch-active? (complete-animation))) + 200)) + reset-x-y-animation (fn [] + (helpers/animate-easing translate-y 0 300) + (helpers/animate-easing translate-x 0 300) + (helpers/animate-linear icon-opacity 1 500) + (helpers/animate-linear gray-overlay-opacity 0 800) + (js/setTimeout (fn [] + (reset! record-button-at-initial-position? true)) + 800))] + (use-effect (fn [] (cond - @ready-to-send? - (when on-send - (on-send {:file-path (audio/get-recorder-file-path @recorder-ref) - :duration @recording-length-ms})) - @ready-to-delete? - (when on-cancel - (on-cancel))) - (reload-recorder-fn) - (reset! recording? false) - (reset! ready-to-send? false) - (reset! ready-to-delete? false) - (reset! ready-to-lock? false) - (reset! idle? true) - (js/setTimeout #(reset! idle? false) 1000) - (js/clearInterval @recording-timer) - (reset! recording-length-ms 0) - (log/debug "[record-audio] stop recording - success")) - #(log/error "[record-audio] stop recording - error: " %)))) - start-animation (fn [] - (helpers/set-value opacity 1) - (helpers/animate-linear scale 2.6 signal-anim-duration) - ;; TODO: Research if we can implement this with withSequence method - ;; from Reanimated 2 - ;; GitHub issue [#14561]: - ;; https://github.com/status-im/status-mobile/issues/14561 - (reset! clear-timeout - (js/setTimeout - (fn [] - (helpers/set-value scale scale-to-each) - (helpers/animate-linear-with-delay-loop scale - scale-to-total - signal-anim-duration-2 - 0)) - signal-anim-duration))) - stop-animation (fn [] - (helpers/set-value opacity 0) - (reanimated/cancel-animation scale) - (helpers/set-value scale 1) - (when @clear-timeout (js/clearTimeout @clear-timeout))) - start-y-animation (fn [] - (reset! record-button-at-initial-position? false) - (reset! record-button-is-animating? true) - (helpers/animate-easing translate-y -64 250) - (helpers/animate-linear-with-delay icon-opacity 0 33.33 76.66) - (js/setTimeout (fn [] - (reset! record-button-is-animating? false) - (when-not @touch-active? (complete-animation))) - 250)) - reset-y-animation (fn [] - (helpers/animate-easing translate-y 0 300) - (helpers/animate-linear icon-opacity 1 500) - (js/setTimeout (fn [] - (reset! record-button-at-initial-position? true)) - 500)) - start-x-animation (fn [] - (reset! record-button-at-initial-position? false) - (reset! record-button-is-animating? true) - (helpers/animate-easing translate-x -64 250) - (helpers/animate-linear-with-delay icon-opacity 0 33.33 76.66) - (helpers/animate-linear red-overlay-opacity 1 33.33) - (js/setTimeout (fn [] - (reset! record-button-is-animating? false) - (when-not @touch-active? (complete-animation))) - 250)) - reset-x-animation (fn [] - (helpers/animate-easing translate-x 0 300) - (helpers/animate-linear icon-opacity 1 500) - (helpers/animate-linear red-overlay-opacity 0 100) - (js/setTimeout (fn [] - (reset! record-button-at-initial-position? true)) - 500)) - start-x-y-animation (fn [] - (reset! record-button-at-initial-position? false) - (reset! record-button-is-animating? true) - (helpers/animate-easing translate-y -44 200) - (helpers/animate-easing translate-x -44 200) - (helpers/animate-linear-with-delay icon-opacity 0 33.33 33.33) - (helpers/animate-linear gray-overlay-opacity 1 33.33) - (js/setTimeout (fn [] - (reset! record-button-is-animating? false) - (when-not @touch-active? (complete-animation))) - 200)) - reset-x-y-animation (fn [] - (helpers/animate-easing translate-y 0 300) - (helpers/animate-easing translate-x 0 300) - (helpers/animate-linear icon-opacity 1 500) - (helpers/animate-linear gray-overlay-opacity 0 800) - (js/setTimeout (fn [] - (reset! record-button-at-initial-position? true)) - 800))] - (use-effect (fn [] - (cond - @recording? - (start-animation) - (not @ready-to-lock?) - (stop-animation))) - [@recording?]) - (use-effect (fn [] - (if @ready-to-lock? - (start-x-y-animation) - (reset-x-y-animation))) - [@ready-to-lock?]) - (use-effect (fn [] - (if @ready-to-send? - (start-y-animation) - (reset-y-animation))) - [@ready-to-send?]) - (use-effect (fn [] - (if @ready-to-delete? - (start-x-animation) - (reset-x-animation))) - [@ready-to-delete?]) - [reanimated/view - {:style (style/record-button-big-container translate-x translate-y opacity) - :pointer-events :none} - [:<> - (map-indexed - (fn [id animation] - ^{:key id} - [animated-ring - {:scale (:scale animation) - :opacity (:opacity animation) - :color rings-color}]) - animations)] - [rn/view {:style (style/record-button-big-body button-color)} - [reanimated/view {:style (style/record-button-big-red-overlay red-overlay-opacity)}] - [reanimated/view {:style (style/record-button-big-gray-overlay gray-overlay-opacity)}] - [reanimated/view {:style (style/record-button-big-icon-container icon-opacity)} - (if @locked? - [rn/view {:style style/stop-icon}] - [icons/icon :i/audio {:color icon-color}])]]]))]) + @recording? + (start-animation) + (not @ready-to-lock?) + (stop-animation))) + [@recording?]) + (use-effect (fn [] + (if @ready-to-lock? + (start-x-y-animation) + (reset-x-y-animation))) + [@ready-to-lock?]) + (use-effect (fn [] + (if @ready-to-send? + (start-y-animation) + (reset-y-animation))) + [@ready-to-send?]) + (use-effect (fn [] + (if @ready-to-delete? + (start-x-animation) + (reset-x-animation))) + [@ready-to-delete?]) + [reanimated/view + {:style (style/record-button-big-container translate-x translate-y opacity) + :pointer-events :none} + [:<> + (map-indexed + (fn [id animation] + ^{:key id} + [animated-ring + {:scale (:scale animation) + :opacity (:opacity animation) + :color rings-color}]) + animations)] + [rn/view {:style (style/record-button-big-body button-color)} + [reanimated/view {:style (style/record-button-big-red-overlay red-overlay-opacity)}] + [reanimated/view {:style (style/record-button-big-gray-overlay gray-overlay-opacity)}] + [reanimated/view {:style (style/record-button-big-icon-container icon-opacity)} + (if @locked? + [rn/view {:style style/stop-icon}] + [icons/icon :i/audio {:color icon-color}])]]])) diff --git a/src/quo2/components/record_audio/record_audio/buttons/send_button.cljs b/src/quo2/components/record_audio/record_audio/buttons/send_button.cljs index fe696a0ad1..ec5c560018 100644 --- a/src/quo2/components/record_audio/record_audio/buttons/send_button.cljs +++ b/src/quo2/components/record_audio/record_audio/buttons/send_button.cljs @@ -6,88 +6,86 @@ [react-native.core :refer [use-effect]] [quo2.components.record-audio.record-audio.helpers :as helpers])) -(defn send-button +(defn f-send-button [recording? ready-to-send? reviewing-audio? force-show-controls?] - [:f> - (fn [] - (let [opacity (reanimated/use-shared-value (if force-show-controls? 1 0)) - translate-y (reanimated/use-shared-value (if force-show-controls? 76 20)) - connector-opacity (reanimated/use-shared-value 0) - width (reanimated/use-shared-value 12) - height (reanimated/use-shared-value 24) - border-radius-first-half (reanimated/use-shared-value 16) - border-radius-second-half (reanimated/use-shared-value 8) - start-y-animation (fn [] - (helpers/animate-linear-with-delay translate-y 12 50 133.33) - (helpers/animate-easing-with-delay connector-opacity 1 0 93.33) - (helpers/animate-easing-with-delay width 56 83.33 80) - (helpers/animate-easing-with-delay height 56 83.33 80) - (helpers/animate-easing-with-delay border-radius-first-half - 28 - 83.33 - 80) - (helpers/animate-easing-with-delay border-radius-second-half - 28 - 83.33 - 80)) - reset-y-animation (fn [] - (helpers/animate-linear translate-y 0 100) - (helpers/set-value connector-opacity 0) - (helpers/set-value width 12) - (helpers/set-value height 24) - (helpers/set-value border-radius-first-half 16) - (helpers/set-value border-radius-second-half 8)) - fade-in-animation (fn [] - (helpers/animate-linear translate-y 0 200) - (helpers/animate-linear opacity 1 200)) - fade-out-animation (fn [] - (when-not force-show-controls? - (helpers/animate-linear - translate-y - (if @reviewing-audio? 76 20) - 200)) - (when-not @reviewing-audio? - (helpers/animate-linear opacity 0 200)) - (helpers/set-value connector-opacity 0) - (helpers/set-value width 24) - (helpers/set-value height 12) - (helpers/set-value border-radius-first-half 8) - (helpers/set-value border-radius-second-half 16)) - fade-out-reset-animation (fn [] - (helpers/animate-linear opacity 0 200) - (helpers/animate-linear-with-delay translate-y 20 0 200) - (helpers/set-value connector-opacity 0) - (helpers/set-value width 24) - (helpers/set-value height 12) - (helpers/set-value border-radius-first-half 8) - (helpers/set-value border-radius-second-half 16))] - (use-effect (fn [] - (if @recording? - (fade-in-animation) - (fade-out-animation))) - [@recording?]) - (use-effect (fn [] - (when-not @reviewing-audio? - (fade-out-reset-animation))) - [@reviewing-audio?]) - (use-effect (fn [] - (cond - @ready-to-send? - (start-y-animation) - @recording? (reset-y-animation))) - [@ready-to-send?]) - [:<> - [reanimated/view {:style (style/send-button-container opacity)} - [reanimated/view - {:style (style/send-button-connector connector-opacity - width - height - border-radius-first-half - border-radius-second-half)}]] - [reanimated/view - {:style (style/send-button translate-y opacity) - :pointer-events :none} - [icons/icon :i/arrow-up - {:color colors/white - :size 20 - :container-style style/send-icon-container}]]]))]) + (let [opacity (reanimated/use-shared-value (if force-show-controls? 1 0)) + translate-y (reanimated/use-shared-value (if force-show-controls? 76 20)) + connector-opacity (reanimated/use-shared-value 0) + width (reanimated/use-shared-value 12) + height (reanimated/use-shared-value 24) + border-radius-first-half (reanimated/use-shared-value 16) + border-radius-second-half (reanimated/use-shared-value 8) + start-y-animation (fn [] + (helpers/animate-linear-with-delay translate-y 12 50 133.33) + (helpers/animate-easing-with-delay connector-opacity 1 0 93.33) + (helpers/animate-easing-with-delay width 56 83.33 80) + (helpers/animate-easing-with-delay height 56 83.33 80) + (helpers/animate-easing-with-delay border-radius-first-half + 28 + 83.33 + 80) + (helpers/animate-easing-with-delay border-radius-second-half + 28 + 83.33 + 80)) + reset-y-animation (fn [] + (helpers/animate-linear translate-y 0 100) + (helpers/set-value connector-opacity 0) + (helpers/set-value width 12) + (helpers/set-value height 24) + (helpers/set-value border-radius-first-half 16) + (helpers/set-value border-radius-second-half 8)) + fade-in-animation (fn [] + (helpers/animate-linear translate-y 0 200) + (helpers/animate-linear opacity 1 200)) + fade-out-animation (fn [] + (when-not force-show-controls? + (helpers/animate-linear + translate-y + (if @reviewing-audio? 76 20) + 200)) + (when-not @reviewing-audio? + (helpers/animate-linear opacity 0 200)) + (helpers/set-value connector-opacity 0) + (helpers/set-value width 24) + (helpers/set-value height 12) + (helpers/set-value border-radius-first-half 8) + (helpers/set-value border-radius-second-half 16)) + fade-out-reset-animation (fn [] + (helpers/animate-linear opacity 0 200) + (helpers/animate-linear-with-delay translate-y 20 0 200) + (helpers/set-value connector-opacity 0) + (helpers/set-value width 24) + (helpers/set-value height 12) + (helpers/set-value border-radius-first-half 8) + (helpers/set-value border-radius-second-half 16))] + (use-effect (fn [] + (if @recording? + (fade-in-animation) + (fade-out-animation))) + [@recording?]) + (use-effect (fn [] + (when-not @reviewing-audio? + (fade-out-reset-animation))) + [@reviewing-audio?]) + (use-effect (fn [] + (cond + @ready-to-send? + (start-y-animation) + @recording? (reset-y-animation))) + [@ready-to-send?]) + [:<> + [reanimated/view {:style (style/send-button-container opacity)} + [reanimated/view + {:style (style/send-button-connector connector-opacity + width + height + border-radius-first-half + border-radius-second-half)}]] + [reanimated/view + {:style (style/send-button translate-y opacity) + :pointer-events :none} + [icons/icon :i/arrow-up + {:color colors/white + :size 20 + :container-style style/send-icon-container}]]])) diff --git a/src/quo2/components/record_audio/record_audio/view.cljs b/src/quo2/components/record_audio/record_audio/view.cljs index 2504e1be3b..755f4315b7 100644 --- a/src/quo2/components/record_audio/record_audio/view.cljs +++ b/src/quo2/components/record_audio/record_audio/view.cljs @@ -86,71 +86,68 @@ (or ignore-min-y? (>= location-y y)) (or ignore-max-y? (<= location-y max-y)))))) -(defn- recording-bar +(defn- f-recording-bar [recording-length-ms ready-to-delete?] - [:f> - (fn [] - (let [fill-percentage (/ (* recording-length-ms 100) max-audio-duration-ms)] - [rn/view {:style (style/recording-bar-container)} - [rn/view {:style (style/recording-bar fill-percentage ready-to-delete?)}]]))]) + (let [fill-percentage (/ (* recording-length-ms 100) max-audio-duration-ms)] + [rn/view {:style (style/recording-bar-container)} + [rn/view {:style (style/recording-bar fill-percentage ready-to-delete?)}]])) -(defn- time-counter +(defn- f-time-counter [recording? recording-length-ms ready-to-delete? reviewing-audio? audio-current-time-ms] - [:f> - (fn [] - (let [s (quot (if recording? recording-length-ms audio-current-time-ms) 1000) - time-str (gstring/format "%02d:%02d" (quot s 60) (mod s 60))] - [rn/view {:style (style/timer-container reviewing-audio?)} - (when-not reviewing-audio? - [rn/view {:style (style/timer-circle)}]) - [text/text - (merge - {:size :label - :weight :semi-bold} - (when ready-to-delete? - {:style (style/timer-text)})) - time-str]]))]) + (let [s (quot (if recording? recording-length-ms audio-current-time-ms) 1000) + time-str (gstring/format "%02d:%02d" (quot s 60) (mod s 60))] + [rn/view {:style (style/timer-container reviewing-audio?)} + (when-not reviewing-audio? + [rn/view {:style (style/timer-circle)}]) + [text/text + (merge + {:size :label + :weight :semi-bold} + (when ready-to-delete? + {:style (style/timer-text)})) + time-str]])) -(defn- play-button +(defn- f-play-button [playing-audio? player-ref playing-timer audio-current-time-ms seeking-audio?] - [:f> - (fn [] - (let [on-play (fn [] - (reset! playing-audio? true) - (reset! playing-timer - (js/setInterval - (fn [] - (let [current-time (audio/get-player-current-time @player-ref) - player-state (audio/get-state @player-ref) - playing? (= player-state audio/PLAYING)] - (when (and playing? (not @seeking-audio?) (> current-time 0)) - (reset! audio-current-time-ms current-time)))) - 100))) - on-pause (fn [] - (reset! playing-audio? false) - (when @playing-timer - (js/clearInterval @playing-timer) - (reset! playing-timer nil)) - (log/debug "[record-audio] toggle play / pause - success")) - on-press (fn [] - (audio/toggle-playpause-player - @player-ref - on-play - on-pause - #(log/error "[record-audio] toggle play / pause - error: " %)))] - [rn/touchable-opacity - {:style (style/play-button) - :on-press on-press} - [icons/icon - (if @playing-audio? :i/pause :i/play) - {:color (colors/theme-colors colors/neutral-100 colors/white)}]]))]) + (let [on-play (fn [] + (reset! playing-audio? true) + (reset! playing-timer + (js/setInterval + (fn [] + (let [current-time (audio/get-player-current-time @player-ref) + player-state (audio/get-state @player-ref) + playing? (= player-state audio/PLAYING)] + (when (and playing? (not @seeking-audio?) (> current-time 0)) + (reset! audio-current-time-ms current-time)))) + 100))) + on-pause (fn [] + (reset! playing-audio? false) + (when @playing-timer + (js/clearInterval @playing-timer) + (reset! playing-timer nil)) + (log/debug "[record-audio] toggle play / pause - success")) + on-press (fn [] + (audio/toggle-playpause-player + @player-ref + on-play + on-pause + #(log/error "[record-audio] toggle play / pause - error: " %)))] + [rn/touchable-opacity + {:style (style/play-button) + :on-press on-press} + [icons/icon + (if @playing-audio? :i/pause :i/play) + {:color (colors/theme-colors colors/neutral-100 colors/white)}]])) -(defn view +(defn record-audio [{:keys [on-init on-start-recording on-send on-cancel on-reviewing-audio record-audio-permission-granted on-request-record-audio-permission on-check-audio-permissions audio-file]}] [:f> + ;; TODO we need to refactor this, and use :f> with defined function, currenly state is reseted each + ;; time parent component + ;; is re-rendered (fn [] (let [recording? (reagent/atom false) locked? (reagent/atom false) @@ -524,16 +521,17 @@ :pointer-events :box-none} (when @reviewing-audio? [:<> - [play-button playing-audio? player-ref playing-timer audio-current-time-ms seeking-audio?] - [soundtrack/soundtrack + [:f> f-play-button playing-audio? player-ref playing-timer audio-current-time-ms + seeking-audio?] + [:f> soundtrack/f-soundtrack {:audio-current-time-ms audio-current-time-ms :player-ref player-ref :seeking-audio? seeking-audio?}]]) (when (or @recording? @reviewing-audio?) - [time-counter @recording? @recording-length-ms @ready-to-delete? @reviewing-audio? + [:f> f-time-counter @recording? @recording-length-ms @ready-to-delete? @reviewing-audio? @audio-current-time-ms]) (when @recording? - [recording-bar @recording-length-ms @ready-to-delete?]) + [:f> f-recording-bar @recording-length-ms @ready-to-delete?]) [rn/view {:test-ID "record-audio" :style style/button-container @@ -545,11 +543,12 @@ :on-start-should-set-responder on-start-should-set-responder :on-responder-move on-responder-move :on-responder-release on-responder-release} - [delete-button/delete-button recording? ready-to-delete? reviewing-audio? + [:f> delete-button/f-delete-button recording? ready-to-delete? reviewing-audio? @force-show-controls?] - [lock-button/lock-button recording? ready-to-lock? locked?] - [send-button/send-button recording? ready-to-send? reviewing-audio? @force-show-controls?] - [record-button-big/record-button-big + [:f> lock-button/f-lock-button recording? ready-to-lock? locked?] + [:f> send-button/f-send-button recording? ready-to-send? reviewing-audio? + @force-show-controls?] + [:f> record-button-big/f-record-button-big recording? ready-to-send? ready-to-lock? @@ -567,6 +566,4 @@ idle? on-send on-cancel] - [record-button/record-button recording? reviewing-audio?]]])))]) - -(def record-audio view) + [:f> record-button/f-record-button recording? reviewing-audio?]]])))]) diff --git a/src/quo2/components/record_audio/soundtrack/__tests__/soundtrack_component_spec.cljs b/src/quo2/components/record_audio/soundtrack/__tests__/soundtrack_component_spec.cljs index ef343ca0a2..d5c2c42caa 100644 --- a/src/quo2/components/record_audio/soundtrack/__tests__/soundtrack_component_spec.cljs +++ b/src/quo2/components/record_audio/soundtrack/__tests__/soundtrack_component_spec.cljs @@ -18,7 +18,7 @@ (with-redefs [audio/get-player-duration (fn [] 2000)] (let [player-ref (reagent/atom {}) audio-current-time-ms (reagent/atom 0)] - (h/render [soundtrack/soundtrack + (h/render [:f> soundtrack/f-soundtrack {:player-ref player-ref :audio-current-time-ms audio-current-time-ms}]) (-> (h/expect (h/get-by-test-id "soundtrack")) @@ -29,7 +29,7 @@ (let [seeking-audio? (reagent/atom false) player-ref (reagent/atom {}) audio-current-time-ms (reagent/atom 0)] - (h/render [soundtrack/soundtrack + (h/render [:f> soundtrack/f-soundtrack {:seeking-audio? seeking-audio? :player-ref player-ref :audio-current-time-ms audio-current-time-ms}]) @@ -45,7 +45,7 @@ (let [seeking-audio? (reagent/atom false) player-ref (reagent/atom {}) audio-current-time-ms (reagent/atom 0)] - (h/render [soundtrack/soundtrack + (h/render [:f> soundtrack/f-soundtrack {:seeking-audio? seeking-audio? :player-ref player-ref :audio-current-time-ms audio-current-time-ms}]) @@ -67,7 +67,7 @@ (let [seeking-audio? (reagent/atom false) player-ref (reagent/atom {}) audio-current-time-ms (reagent/atom 0)] - (h/render [soundtrack/soundtrack + (h/render [:f> soundtrack/f-soundtrack {:seeking-audio? seeking-audio? :player-ref player-ref :audio-current-time-ms audio-current-time-ms}]) diff --git a/src/quo2/components/record_audio/soundtrack/view.cljs b/src/quo2/components/record_audio/soundtrack/view.cljs index 0a0e6c9a2f..62889c63ce 100644 --- a/src/quo2/components/record_audio/soundtrack/view.cljs +++ b/src/quo2/components/record_audio/soundtrack/view.cljs @@ -9,30 +9,28 @@ (def ^:private thumb-light (js/require "../resources/images/icons2/12x12/thumb-light.png")) (def ^:private thumb-dark (js/require "../resources/images/icons2/12x12/thumb-dark.png")) -(defn soundtrack +(defn f-soundtrack [{:keys [audio-current-time-ms player-ref seeking-audio?]}] - [:f> - (fn [] - (let [audio-duration-ms (audio/get-player-duration @player-ref)] - [:<> - [slider/slider - {:test-ID "soundtrack" - :style (style/player-slider-container) - :minimum-value 0 - :maximum-value audio-duration-ms - :value @audio-current-time-ms - :on-sliding-start #(reset! seeking-audio? true) - :on-sliding-complete (fn [seek-time] - (reset! seeking-audio? false) - (audio/seek-player - @player-ref - seek-time - #(log/debug "[record-audio] on seek - seek time: " seek-time) - #(log/error "[record-audio] on seek - error: " %))) - :on-value-change #(when @seeking-audio? - (reset! audio-current-time-ms %)) - :thumb-image (if (colors/dark?) thumb-dark thumb-light) - :minimum-track-tint-color (colors/theme-colors colors/primary-50 colors/primary-60) - :maximum-track-tint-color (colors/theme-colors - (if platform/ios? colors/neutral-20 colors/neutral-40) - (if platform/ios? colors/neutral-80 colors/neutral-60))}]]))]) + (let [audio-duration-ms (audio/get-player-duration @player-ref)] + [:<> + [slider/slider + {:test-ID "soundtrack" + :style (style/player-slider-container) + :minimum-value 0 + :maximum-value audio-duration-ms + :value @audio-current-time-ms + :on-sliding-start #(reset! seeking-audio? true) + :on-sliding-complete (fn [seek-time] + (reset! seeking-audio? false) + (audio/seek-player + @player-ref + seek-time + #(log/debug "[record-audio] on seek - seek time: " seek-time) + #(log/error "[record-audio] on seek - error: " %))) + :on-value-change #(when @seeking-audio? + (reset! audio-current-time-ms %)) + :thumb-image (if (colors/dark?) thumb-dark thumb-light) + :minimum-track-tint-color (colors/theme-colors colors/primary-50 colors/primary-60) + :maximum-track-tint-color (colors/theme-colors + (if platform/ios? colors/neutral-20 colors/neutral-40) + (if platform/ios? colors/neutral-80 colors/neutral-60))}]])) diff --git a/src/react_native/core.cljs b/src/react_native/core.cljs index ae83a6a4c4..873fba343c 100644 --- a/src/react_native/core.cljs +++ b/src/react_native/core.cljs @@ -37,14 +37,6 @@ (def dismiss-keyboard! #(.dismiss keyboard)) -(defn use-window-dimensions - [] - (let [window ^js (react-native/useWindowDimensions)] - {:font-scale (.-fontScale window) - :height (.-height window) - :scale (.-scale window) - :width (.-width window)})) - (defn hide-splash-screen [] (.hide ^js (-> react-native .-NativeModules .-SplashScreen))) @@ -63,17 +55,15 @@ [handler] (.addChangeListener appearance handler)) -(defn get-window - [] - (js->clj (.get (.-Dimensions ^js react-native) "window") :keywordize-keys true)) +(def get-window + (memoize + (fn [] + (js->clj (.get (.-Dimensions ^js react-native) "window") :keywordize-keys true)))) -(def status-bar (.-StatusBar ^js react-native)) - -(def style-sheet (.-StyleSheet ^js react-native)) - -(defn status-bar-height - [] - (.-currentHeight ^js status-bar)) +(def get-screen + (memoize + (fn [] + (js->clj (.get (.-Dimensions ^js react-native) "screen") :keywordize-keys true)))) (defn hw-back-add-listener [callback] diff --git a/src/react_native/safe_area.cljs b/src/react_native/safe_area.cljs index 02b41f31ab..d5a371299b 100644 --- a/src/react_native/safe_area.cljs +++ b/src/react_native/safe_area.cljs @@ -1,23 +1,30 @@ (ns react-native.safe-area - (:require ["react-native-safe-area-context" :as safe-area-context :refer - (SafeAreaProvider SafeAreaInsetsContext useSafeAreaInsets)] - [reagent.core :as reagent])) + (:require ["react-native-static-safe-area-insets" :default StaticSafeAreaInsets] + [oops.core :as oops] + [react-native.platform :as platform] + [react-native.navigation :as navigation])) -(def ^:private consumer-raw (reagent/adapt-react-class (.-Consumer ^js SafeAreaInsetsContext))) - -(def provider (reagent/adapt-react-class SafeAreaProvider)) - -(defn consumer - [component] - [consumer-raw - (fn [^js insets] - (reagent/as-element - [component (js->clj insets :keywordize-keys true)]))]) - -(defn use-safe-area +(defn- get-static-top [] - (let [insets ^js (useSafeAreaInsets)] - {:top (.-top insets) - :bottom (.-bottom insets) - :left (.-left insets) - :right (.-right insets)})) + (oops/oget StaticSafeAreaInsets "safeAreaInsetsTop")) + +(defn- get-static-bottom + [] + (oops/oget StaticSafeAreaInsets "safeAreaInsetsBottom")) + +(defn get-top + [] + (if platform/ios? + (get-static-top) + (navigation/status-bar-height))) + +(defn get-bottom + [] + (if platform/ios? + (get-static-bottom) + 0)) + +(defn get-insets + [] + {:top (get-top) + :bottom (get-bottom)}) diff --git a/src/status_im/bottom_sheet/view.cljs b/src/status_im/bottom_sheet/view.cljs index d4fa7c542d..80ce8f9829 100644 --- a/src/status_im/bottom_sheet/view.cljs +++ b/src/status_im/bottom_sheet/view.cljs @@ -115,126 +115,125 @@ (re-frame/dispatch [:bottom-sheet/hide-old-navigation-overlay]) (reset-atoms)) animation-delay))] - [safe-area/consumer - (fn [insets] - [:f> - (fn [] - (let [{height :height - window-width :width} - (rn/use-window-dimensions) - window-height (if selected-item (- height 72) height) - {:keys [keyboard-shown]} (hooks/use-keyboard) - bg-height-expanded (- window-height (:top insets)) - bg-height (max (min @content-height bg-height-expanded) 109) - bottom-sheet-dy (reanimated/use-shared-value 0) - pan-y (reanimated/use-shared-value 0) - translate-y (worklets.bottom-sheet/use-translate-y window-height bottom-sheet-dy pan-y) - bg-opacity - (worklets.bottom-sheet/use-background-opacity translate-y bg-height window-height 0.7) - on-content-layout (fn [evt] - (let [height (oget evt "nativeEvent" "layout" "height")] - (reset! content-height height))) - on-expanded (fn [] - (reanimated/set-shared-value bottom-sheet-dy bg-height-expanded) - (reanimated/set-shared-value pan-y 0)) - on-collapsed (fn [] - (reanimated/set-shared-value bottom-sheet-dy bg-height) - (reanimated/set-shared-value pan-y 0)) - bottom-sheet-gesture (get-bottom-sheet-gesture - pan-y - translate-y - bg-height - bg-height-expanded - window-height - keyboard-shown - disable-drag? - expandable? - show-bottom-sheet? - expanded? - close-bottom-sheet - gesture-running?) - handle-comp [gesture/gesture-detector {:gesture bottom-sheet-gesture} - [handle-comp window-width override-theme]]] + [:f> + (fn [] + (let [{height :height + window-width :width} + (rn/get-window) + window-height (if selected-item (- height 72) height) + {:keys [keyboard-shown]} (hooks/use-keyboard) + insets (safe-area/get-insets) + bg-height-expanded (- window-height (:top insets)) + bg-height (max (min @content-height bg-height-expanded) 109) + bottom-sheet-dy (reanimated/use-shared-value 0) + pan-y (reanimated/use-shared-value 0) + translate-y (worklets.bottom-sheet/use-translate-y window-height bottom-sheet-dy pan-y) + bg-opacity + (worklets.bottom-sheet/use-background-opacity translate-y bg-height window-height 0.7) + on-content-layout (fn [evt] + (let [height (oget evt "nativeEvent" "layout" "height")] + (reset! content-height height))) + on-expanded (fn [] + (reanimated/set-shared-value bottom-sheet-dy bg-height-expanded) + (reanimated/set-shared-value pan-y 0)) + on-collapsed (fn [] + (reanimated/set-shared-value bottom-sheet-dy bg-height) + (reanimated/set-shared-value pan-y 0)) + bottom-sheet-gesture (get-bottom-sheet-gesture + pan-y + translate-y + bg-height + bg-height-expanded + window-height + keyboard-shown + disable-drag? + expandable? + show-bottom-sheet? + expanded? + close-bottom-sheet + gesture-running?) + handle-comp [gesture/gesture-detector {:gesture bottom-sheet-gesture} + [handle-comp window-width override-theme]]] - (react/effect! #(do - (cond - (and - (nil? @show-bottom-sheet?) - visible? - (some? @content-height) - (> @content-height 0)) - (reset! show-bottom-sheet? true) + (react/effect! #(do + (cond + (and + (nil? @show-bottom-sheet?) + visible? + (some? @content-height) + (> @content-height 0)) + (reset! show-bottom-sheet? true) - (and @show-bottom-sheet? (not visible?)) - (close-bottom-sheet))) - [@show-bottom-sheet? @content-height visible?]) - (react/effect! #(do - (when @show-bottom-sheet? - (cond - keyboard-shown - (do - (reset! keyboard-was-shown? true) - (reset! expanded? true)) - (and @keyboard-was-shown? (not keyboard-shown)) - (reset! expanded? false)))) - [@show-bottom-sheet? @keyboard-was-shown? keyboard-shown]) - (react/effect! #(do - (when-not @gesture-running? - (cond - @show-bottom-sheet? - (if @expanded? - (do - (reanimated/set-shared-value - bottom-sheet-dy - (with-animation (+ bg-height-expanded (.-value pan-y)))) - ;; Workaround for - ;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741 - ;; withTiming/withSpring callback not working - ;; on-expanded should be called as a callback of - ;; with-animation instead, once this issue has been resolved - (timer/set-timeout on-expanded animation-delay)) - (do - (reanimated/set-shared-value - bottom-sheet-dy - (with-animation (+ bg-height (.-value pan-y)))) - ;; Workaround for - ;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741 - ;; withTiming/withSpring callback not working - ;; on-collapsed should be called as a callback of - ;; with-animation instead, once this issue has been resolved - (timer/set-timeout on-collapsed animation-delay))) + (and @show-bottom-sheet? (not visible?)) + (close-bottom-sheet))) + [@show-bottom-sheet? @content-height visible?]) + (react/effect! #(do + (when @show-bottom-sheet? + (cond + keyboard-shown + (do + (reset! keyboard-was-shown? true) + (reset! expanded? true)) + (and @keyboard-was-shown? (not keyboard-shown)) + (reset! expanded? false)))) + [@show-bottom-sheet? @keyboard-was-shown? keyboard-shown]) + (react/effect! #(do + (when-not @gesture-running? + (cond + @show-bottom-sheet? + (if @expanded? + (do + (reanimated/set-shared-value + bottom-sheet-dy + (with-animation (+ bg-height-expanded (.-value pan-y)))) + ;; Workaround for + ;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741 + ;; withTiming/withSpring callback not working + ;; on-expanded should be called as a callback of + ;; with-animation instead, once this issue has been resolved + (timer/set-timeout on-expanded animation-delay)) + (do + (reanimated/set-shared-value + bottom-sheet-dy + (with-animation (+ bg-height (.-value pan-y)))) + ;; Workaround for + ;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741 + ;; withTiming/withSpring callback not working + ;; on-collapsed should be called as a callback of + ;; with-animation instead, once this issue has been resolved + (timer/set-timeout on-collapsed animation-delay))) - (= @show-bottom-sheet? false) - (reanimated/set-shared-value bottom-sheet-dy (with-animation 0))))) - [@show-bottom-sheet? @expanded? @gesture-running?]) + (= @show-bottom-sheet? false) + (reanimated/set-shared-value bottom-sheet-dy (with-animation 0))))) + [@show-bottom-sheet? @expanded? @gesture-running?]) - [:<> - [rn/touchable-without-feedback {:on-press (when backdrop-dismiss? close-bottom-sheet)} - [reanimated/view - {:style (reanimated/apply-animations-to-style - {:opacity bg-opacity} - styles/backdrop)}]] - (cond->> [reanimated/view - {:style (reanimated/apply-animations-to-style - {:transform [{:translateY translate-y}]} - {:width window-width - :height window-height})} - [rn/view {:style styles/container} - (when selected-item - [rn/view {:style (styles/selected-background override-theme)} - [selected-item]]) - [rn/view {:style (styles/background override-theme)} - [rn/keyboard-avoiding-view - {:behaviour (if platform/ios? :padding :height) - :style {:flex 1}} - [rn/view - {:style (styles/content-style insets bottom-safe-area-spacing?) - :on-layout (when-not (and - (some? @content-height) - (> @content-height 0)) - on-content-layout)} - children]] - (when show-handle? - handle-comp)]]] - (not show-handle?) - (conj [gesture/gesture-detector {:gesture bottom-sheet-gesture}]))]))])])) + [:<> + [rn/touchable-without-feedback {:on-press (when backdrop-dismiss? close-bottom-sheet)} + [reanimated/view + {:style (reanimated/apply-animations-to-style + {:opacity bg-opacity} + styles/backdrop)}]] + (cond->> [reanimated/view + {:style (reanimated/apply-animations-to-style + {:transform [{:translateY translate-y}]} + {:width window-width + :height window-height})} + [rn/view {:style styles/container} + (when selected-item + [rn/view {:style (styles/selected-background override-theme)} + [selected-item]]) + [rn/view {:style (styles/background override-theme)} + [rn/keyboard-avoiding-view + {:behaviour (if platform/ios? :padding :height) + :style {:flex 1}} + [rn/view + {:style (styles/content-style insets bottom-safe-area-spacing?) + :on-layout (when-not (and + (some? @content-height) + (> @content-height 0)) + on-content-layout)} + children]] + (when show-handle? + handle-comp)]]] + (not show-handle?) + (conj [gesture/gesture-detector {:gesture bottom-sheet-gesture}]))]))])) diff --git a/src/status_im/ui/components/keyboard_avoid_presentation.cljs b/src/status_im/ui/components/keyboard_avoid_presentation.cljs index e44ba3e79f..178667e7e1 100644 --- a/src/status_im/ui/components/keyboard_avoid_presentation.cljs +++ b/src/status_im/ui/components/keyboard_avoid_presentation.cljs @@ -1,6 +1,5 @@ (ns status-im.ui.components.keyboard-avoid-presentation - (:require [oops.core :refer [oget]] - [reagent.core :as reagent] + (:require [reagent.core :as reagent] [status-im.ui.components.react :as react])) (defn keyboard-avoiding-view @@ -8,16 +7,11 @@ (let [this (reagent/current-component) props (reagent/props this) children (reagent/children this)] - [react/safe-area-consumer - (fn [insets] - (let [vertical-offset (+ (oget insets "top") - ;; 20 is the margin-top for presentation modal - 20)] - (reagent/as-element - (into [react/keyboard-avoiding-view - (update props - :keyboardVerticalOffset - + - vertical-offset - (if (:ignore-offset props) 44 0))] - children))))])) + (reagent/as-element + (into [react/keyboard-avoiding-view + (update props + :keyboardVerticalOffset + + + 20 + (if (:ignore-offset props) 44 0))] + children)))) diff --git a/src/status_im/ui/components/react.cljs b/src/status_im/ui/components/react.cljs index 92f82a4ee6..a6218b2f22 100644 --- a/src/status_im/ui/components/react.cljs +++ b/src/status_im/ui/components/react.cljs @@ -8,8 +8,6 @@ ["react-native-image-crop-picker" :default image-picker] ["react-native-linear-gradient" :default LinearGradient] ["react-native-navigation" :refer (Navigation)] - ["react-native-safe-area-context" :as safe-area-context :refer - (SafeAreaProvider SafeAreaInsetsContext)] [quo.design-system.colors :as colors] [reagent.core :as reagent] [utils.i18n :as i18n] @@ -308,9 +306,6 @@ [activity-indicator {:animating true}]]) comp))) -(def safe-area-provider (reagent/adapt-react-class SafeAreaProvider)) -(def safe-area-consumer (reagent/adapt-react-class (.-Consumer ^js SafeAreaInsetsContext))) - (defn hw-back-add-listener [callback] (.addEventListener BackHandler "hardwareBackPress" callback)) diff --git a/src/status_im/ui/components/topbar.cljs b/src/status_im/ui/components/topbar.cljs index c21d81a29d..0ea60ec383 100644 --- a/src/status_im/ui/components/topbar.cljs +++ b/src/status_im/ui/components/topbar.cljs @@ -1,7 +1,8 @@ (ns status-im.ui.components.topbar (:require [re-frame.core :as re-frame] [quo.core :as quo] - [quo2.foundations.colors :as quo2.colors])) + [quo2.foundations.colors :as quo2.colors] + [react-native.safe-area :as safe-area])) (def default-button-width 48) @@ -32,18 +33,16 @@ (let [navigation (if (= navigation :none) nil [(default-navigation modal? navigation)])] - [quo/safe-area-consumer - (fn [insets] - [quo/header - (merge {:left-accessories navigation - :title-component content - :insets (when use-insets insets) - :left-width (when navigation - default-button-width) - :border-bottom border-bottom?} - props - (when (seq right-accessories) - {:right-accessories right-accessories}) - (when new-ui? - {:background (quo2.colors/theme-colors quo2.colors/neutral-5 - quo2.colors/neutral-95)}))])])) + [quo/header + (merge {:left-accessories navigation + :title-component content + :insets (when use-insets (safe-area/get-insets)) + :left-width (when navigation + default-button-width) + :border-bottom border-bottom?} + props + (when (seq right-accessories) + {:right-accessories right-accessories}) + (when new-ui? + {:background (quo2.colors/theme-colors quo2.colors/neutral-5 + quo2.colors/neutral-95)}))])) diff --git a/src/status_im/ui/screens/browser/stack.cljs b/src/status_im/ui/screens/browser/stack.cljs index 136a3d0a51..ccf59c7c22 100644 --- a/src/status_im/ui/screens/browser/stack.cljs +++ b/src/status_im/ui/screens/browser/stack.cljs @@ -9,11 +9,9 @@ (defn browser-stack [] (let [screen-id (rf/sub [:browser/screen-id])] - [safe-area/consumer - (fn [{:keys [top]}] - [rn/view {:padding-top top :flex 1} - (case screen-id - :empty-tab [empty-tab/empty-tab] - :browser [browser/browser] - :browser-tabs [tabs/tabs] - [empty-tab/empty-tab])])])) + [rn/view {:padding-top (safe-area/get-top) :flex 1} + (case screen-id + :empty-tab [empty-tab/empty-tab] + :browser [browser/browser] + :browser-tabs [tabs/tabs] + [empty-tab/empty-tab])])) diff --git a/src/status_im/ui/screens/chat/components/accessory.cljs b/src/status_im/ui/screens/chat/components/accessory.cljs index ccfeabd38b..d5739dc96f 100644 --- a/src/status_im/ui/screens/chat/components/accessory.cljs +++ b/src/status_im/ui/screens/chat/components/accessory.cljs @@ -1,14 +1,14 @@ (ns status-im.ui.screens.chat.components.accessory (:require [cljs-bean.core :as bean] [quo.animated :as animated] - [quo.components.safe-area :refer [use-safe-area]] [quo.design-system.colors :as colors] [quo.platform :as platform] [quo.react :as react] [quo.react-native :as rn] [reagent.core :as reagent] [status-im.ui.components.tabbar.core :as tabbar] - [status-im.ui.screens.chat.components.hooks :refer [use-keyboard-dimension]])) + [status-im.ui.screens.chat.components.hooks :refer [use-keyboard-dimension]] + [react-native.safe-area :as safe-area])) (def duration 250) @@ -51,7 +51,7 @@ keyboard-max-height :max-height keyboard-end-position :end-position} (use-keyboard-dimension) - {:keys [bottom]} (use-safe-area) + bottom (safe-area/get-bottom) {on-layout :on-layout bar-height :height} (rn/use-layout) @@ -121,7 +121,7 @@ children :children} (bean/bean props) {keyboard-max-height :max-height} (use-keyboard-dimension) - {:keys [bottom]} (use-safe-area) + bottom (safe-area/get-bottom) {on-layout :on-layout bar-height :height} (rn/use-layout) diff --git a/src/status_im/ui/screens/chat/components/hooks.cljs b/src/status_im/ui/screens/chat/components/hooks.cljs index 8be96943fe..1a674a1f87 100644 --- a/src/status_im/ui/screens/chat/components/hooks.cljs +++ b/src/status_im/ui/screens/chat/components/hooks.cljs @@ -1,8 +1,8 @@ (ns status-im.ui.screens.chat.components.hooks - (:require [quo.components.safe-area :refer [use-safe-area]] - [quo.platform :as platform] + (:require [quo.platform :as platform] [quo.react :as react] - [quo.react-native :refer [use-window-dimensions] :as rn])) + [quo.react-native :refer [use-window-dimensions] :as rn] + [react-native.safe-area :as safe-area])) (def ^:private keyboard-change-event (if platform/android? "keyboardDidShow" "keyboardWillChangeFrame")) @@ -12,7 +12,7 @@ (defn use-keyboard-dimension [] (let [{:keys [height]} (use-window-dimensions) - {:keys [bottom]} (use-safe-area) + bottom (safe-area/get-bottom) keyboard-listener (atom nil) keyboard (react/state {:height 0 diff --git a/src/status_im/ui/screens/chat/image/preview/views.cljs b/src/status_im/ui/screens/chat/image/preview/views.cljs index 45a08b872b..0a409eaf1d 100644 --- a/src/status_im/ui/screens/chat/image/preview/views.cljs +++ b/src/status_im/ui/screens/chat/image/preview/views.cljs @@ -1,6 +1,5 @@ (ns status-im.ui.screens.chat.image.preview.views (:require ["react-native-image-viewing" :default image-viewing] - [quo.components.safe-area :as safe-area] [quo.design-system.colors :as colors] [quo.platform :as platform] [re-frame.core :as re-frame] @@ -9,7 +8,8 @@ [status-im.ui.components.icons.icons :as icons] [status-im.ui.components.react :as react] [status-im.utils.share :as share] - [taoensso.timbre :as log])) + [taoensso.timbre :as log] + [react-native.safe-area :as safe-area])) (defn share [path] @@ -53,29 +53,27 @@ (defn header [{:keys [on-close] :as props}] - [safe-area/consumer - (fn [insets] + [react/view + {:style {:padding-horizontal 15 + :padding-top (+ (safe-area/get-bottom) 50)}} + [react/view {:style {:justify-content :center}} + [react/touchable-opacity + {:on-press on-close + :style {:padding-vertical 11 + :border-radius 44} + :accessibility-label :close-button} [react/view - {:style {:padding-horizontal 15 - :padding-top (+ (:bottom insets) 50)}} - [react/view {:style {:justify-content :center}} - [react/touchable-opacity - {:on-press on-close - :style {:padding-vertical 11 - :border-radius 44} - :accessibility-label :close-button} - [react/view - {:style {:background-color colors/black-transparent-86 - :border-radius 20 - :width 40 - :height 40 - :justify-content :center - :align-items :center}} - [icons/icon :main-icons/close - {:container-style {:width 24 - :height 24} - :color colors/white-persist}]]] - [header-options props]]])]) + {:style {:background-color colors/black-transparent-86 + :border-radius 20 + :width 40 + :height 40 + :justify-content :center + :align-items :center}} + [icons/icon :main-icons/close + {:container-style {:width 24 + :height 24} + :color colors/white-persist}]]] + [header-options props]]]) (defn preview-image [{{:keys [content] :as message} :message diff --git a/src/status_im/ui/screens/wallet/accounts/views.cljs b/src/status_im/ui/screens/wallet/accounts/views.cljs index 934bcdc501..48af22100d 100644 --- a/src/status_im/ui/screens/wallet/accounts/views.cljs +++ b/src/status_im/ui/screens/wallet/accounts/views.cljs @@ -299,39 +299,36 @@ (defn accounts-overview [] (let [mnemonic @(re-frame/subscribe [:mnemonic]) - ;mainnet? @(re-frame/subscribe [:mainnet?]) selected-account-atom (reagent/atom nil)] (fn [] - [safe-area/consumer - (fn [{:keys [top]}] - [react/view - {:style {:flex 1 - :padding-top top - :background-color (quo2.colors/theme-colors quo2.colors/neutral-5 - quo2.colors/neutral-95)}} - [react/view {:padding-horizontal 20} - [react/view {:flex-direction :row :height 56 :align-items :center :justify-content :flex-end} - [quo2.button/button - {:icon true - :size 32 - :type :grey - :accessibility-label :accounts-qr-code - :on-press #(re-frame/dispatch - [::qr-scanner/scan-code - {:handler :wallet.send/qr-scanner-result}])} - :i/placeholder] - [react/view {:width 12}] - [quo2.button/button - {:icon true - :size 32 - :type :grey - :on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old - {:content (sheets/accounts-options mnemonic)}]) - :accessibility-label :accounts-more-options} - :i/placeholder]] - [total-value] - [accounts selected-account-atom]] - [account.views/account-new @selected-account-atom]])]))) + [react/view + {:style {:flex 1 + :padding-top (safe-area/get-top) + :background-color (quo2.colors/theme-colors quo2.colors/neutral-5 + quo2.colors/neutral-95)}} + [react/view {:padding-horizontal 20} + [react/view {:flex-direction :row :height 56 :align-items :center :justify-content :flex-end} + [quo2.button/button + {:icon true + :size 32 + :type :grey + :accessibility-label :accounts-qr-code + :on-press #(re-frame/dispatch + [::qr-scanner/scan-code + {:handler :wallet.send/qr-scanner-result}])} + :i/placeholder] + [react/view {:width 12}] + [quo2.button/button + {:icon true + :size 32 + :type :grey + :on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old + {:content (sheets/accounts-options mnemonic)}]) + :accessibility-label :accounts-more-options} + :i/placeholder]] + [total-value] + [accounts selected-account-atom]] + [account.views/account-new @selected-account-atom]]))) (defn accounts-overview-old [] diff --git a/src/status_im/ui2/screens/chat/components/new_chat/view.cljs b/src/status_im/ui2/screens/chat/components/new_chat/view.cljs index 13044b87ef..e8eb5975a1 100644 --- a/src/status_im/ui2/screens/chat/components/new_chat/view.cljs +++ b/src/status_im/ui2/screens/chat/components/new_chat/view.cljs @@ -60,62 +60,60 @@ (defn contact-selection-list [{:keys [scroll-enabled on-scroll]}] - [:f> - (fn [] - (let [contacts (rf/sub [:contacts/sorted-and-grouped-by-first-letter]) - selected-contacts-count (rf/sub [:selected-contacts-count]) - selected-contacts (rf/sub [:group/selected-contacts]) - one-contact-selected? (= selected-contacts-count 1) - contacts-selected? (pos? selected-contacts-count) - {:keys [primary-name public-key]} (when one-contact-selected? - (rf/sub [:contacts/contact-by-identity - (first selected-contacts)])) - no-contacts? (empty? contacts)] - [:<> - [quo2/button - {:type :grey - :icon true - :on-press #(rf/dispatch [:navigate-back]) - :style style/contact-selection-close - :override-background-color (quo2.colors/theme-colors quo2.colors/neutral-10 - quo2.colors/neutral-90)} - :i/close] - [rn/view style/contact-selection-heading - [quo2/text - {:weight :semi-bold - :size :heading-1 - :style {:color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white)}} - (i18n/label :t/new-chat)] - (when-not no-contacts? - [quo2/text - {:size :paragraph-2 - :weight :regular - :style {:color (quo2.colors/theme-colors quo2.colors/neutral-40 quo2.colors/neutral-50)}} - (i18n/label :t/selected-count-from-max - {:selected selected-contacts-count - :max constants/max-group-chat-participants})])] - [rn/view - {:style {:flex 1}} - (if no-contacts? - [no-contacts-view] - [gesture/section-list - {:key-fn :title - :sticky-section-headers-enabled false - :sections (rf/sub [:contacts/filtered-active-sections]) - :render-section-header-fn contact-list/contacts-section-header - :content-container-style {:padding-bottom 70} - :render-fn contact-item-render - :scroll-enabled @scroll-enabled - :on-scroll on-scroll}])] - (when contacts-selected? - [button/button - {:type :primary - :style style/chat-button - :accessibility-label :next-button - :on-press (fn [] - (if one-contact-selected? - (rf/dispatch [:chat.ui/start-chat public-key]) - (rf/dispatch [:navigate-to :new-group])))} - (if one-contact-selected? - (i18n/label :t/chat-with {:selected-user primary-name}) - (i18n/label :t/setup-group-chat))])]))]) + (let [contacts (rf/sub [:contacts/sorted-and-grouped-by-first-letter]) + selected-contacts-count (rf/sub [:selected-contacts-count]) + selected-contacts (rf/sub [:group/selected-contacts]) + one-contact-selected? (= selected-contacts-count 1) + contacts-selected? (pos? selected-contacts-count) + {:keys [primary-name public-key]} (when one-contact-selected? + (rf/sub [:contacts/contact-by-identity + (first selected-contacts)])) + no-contacts? (empty? contacts)] + [:<> + [quo2/button + {:type :grey + :icon true + :on-press #(rf/dispatch [:navigate-back]) + :style style/contact-selection-close + :override-background-color (quo2.colors/theme-colors quo2.colors/neutral-10 + quo2.colors/neutral-90)} + :i/close] + [rn/view style/contact-selection-heading + [quo2/text + {:weight :semi-bold + :size :heading-1 + :style {:color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white)}} + (i18n/label :t/new-chat)] + (when-not no-contacts? + [quo2/text + {:size :paragraph-2 + :weight :regular + :style {:color (quo2.colors/theme-colors quo2.colors/neutral-40 quo2.colors/neutral-50)}} + (i18n/label :t/selected-count-from-max + {:selected selected-contacts-count + :max constants/max-group-chat-participants})])] + [rn/view + {:style {:flex 1}} + (if no-contacts? + [no-contacts-view] + [gesture/section-list + {:key-fn :title + :sticky-section-headers-enabled false + :sections (rf/sub [:contacts/filtered-active-sections]) + :render-section-header-fn contact-list/contacts-section-header + :content-container-style {:padding-bottom 70} + :render-fn contact-item-render + :scroll-enabled @scroll-enabled + :on-scroll on-scroll}])] + (when contacts-selected? + [button/button + {:type :primary + :style style/chat-button + :accessibility-label :next-button + :on-press (fn [] + (if one-contact-selected? + (rf/dispatch [:chat.ui/start-chat public-key]) + (rf/dispatch [:navigate-to :new-group])))} + (if one-contact-selected? + (i18n/label :t/chat-with {:selected-user primary-name}) + (i18n/label :t/setup-group-chat))])])) diff --git a/src/status_im/ui2/screens/chat/pin_limit_popover/view.cljs b/src/status_im/ui2/screens/chat/pin_limit_popover/view.cljs deleted file mode 100644 index e17e827dd0..0000000000 --- a/src/status_im/ui2/screens/chat/pin_limit_popover/view.cljs +++ /dev/null @@ -1,61 +0,0 @@ -(ns status-im.ui2.screens.chat.pin-limit-popover.view - (:require [utils.i18n :as i18n] - [quo.react :as react] - [quo2.core :as quo] - [quo2.foundations.colors :as colors] - [react-native.core :as rn] - [react-native.reanimated :as reanimated] - [status-im.ui2.screens.chat.pin-limit-popover.style :as style] - [utils.re-frame :as rf])) - -;; TODO (flexsurfer) this should be an in-app notification component in quo2 -;; https://github.com/status-im/status-mobile/issues/14527 -(defn pin-limit-popover - [chat-id] - [:f> - (fn [] - (let [width (rf/sub [:dimensions/window-width]) - show-pin-limit-modal? (rf/sub [:chats/pin-modal chat-id]) - opacity-animation (reanimated/use-shared-value 0) - z-index-animation (reanimated/use-shared-value -1)] - (react/effect! - #(do - (reanimated/set-shared-value opacity-animation - (reanimated/with-timing (if show-pin-limit-modal? 1 0))) - (reanimated/set-shared-value z-index-animation - (reanimated/with-timing (if show-pin-limit-modal? 10 -1))))) - (when show-pin-limit-modal? - [reanimated/view - {:style (reanimated/apply-animations-to-style - {:opacity opacity-animation - :z-index z-index-animation} - (style/pin-popover width)) - :accessibility-label :pin-limit-popover} - [rn/view {:style (style/pin-alert-container)} - [rn/view {:style style/pin-alert-circle} - [rn/text {:style {:color colors/danger-50}} "!"]]] - [rn/view {:style {:margin-left 8}} - [quo/text {:weight :semi-bold :color (colors/theme-colors colors/white colors/neutral-100)} - (i18n/label :t/cannot-pin-title)] - [quo/text {:size :paragraph-2 :color (colors/theme-colors colors/white colors/neutral-100)} - (i18n/label :t/cannot-pin-desc)] - [rn/touchable-opacity - {:accessibility-label :view-pinned-messages - :active-opacity 1 - :on-press (fn [] - (rf/dispatch [:pin-message/hide-pin-limit-modal chat-id]) - (rf/dispatch [:pin-message/show-pins-bottom-sheet chat-id]) - (rf/dispatch [:dismiss-keyboard])) - :style style/view-pinned-messages} - [quo/text {:size :paragraph-2 :weight :medium :color colors/white} - (i18n/label :t/view-pinned-messages)]]] - [rn/touchable-opacity - {:accessibility-label :close-pin-limit-popover - :active-opacity 1 - :on-press #(rf/dispatch [:pin-message/hide-pin-limit-modal chat-id]) - :style {:position :absolute - :top 16 - :right 16}} - [quo/icon :i/close - {:color (colors/theme-colors colors/white colors/neutral-100) - :size 12}]]])))]) diff --git a/src/status_im2/common/bottom_sheet/view.cljs b/src/status_im2/common/bottom_sheet/view.cljs index 22e4f5909b..363f35a3af 100644 --- a/src/status_im2/common/bottom_sheet/view.cljs +++ b/src/status_im2/common/bottom_sheet/view.cljs @@ -50,7 +50,7 @@ (defn view [{:keys [hide? insets]} {:keys [content override-theme selected-item]}] - (let [{window-height :height} (rn/use-window-dimensions) + (let [{window-height :height} (rn/get-window) bg-opacity (reanimated/use-shared-value 0) translate-y (reanimated/use-shared-value window-height) sheet-gesture (get-sheet-gesture translate-y bg-opacity window-height)] diff --git a/src/status_im2/common/bottom_sheet_screen/view.cljs b/src/status_im2/common/bottom_sheet_screen/view.cljs index b3ae9fd30f..fe16a15a46 100644 --- a/src/status_im2/common/bottom_sheet_screen/view.cljs +++ b/src/status_im2/common/bottom_sheet_screen/view.cljs @@ -2,7 +2,6 @@ (:require [react-native.gesture :as gesture] [react-native.hooks :as hooks] - [react-native.navigation :as navigation] [react-native.platform :as platform] [react-native.reanimated :as reanimated] [oops.core :as oops] @@ -46,37 +45,35 @@ (let [y (oops/oget e "nativeEvent.contentOffset.y")] (reset! curr-scroll y))) -(defn view +(defn f-view [content skip-background?] - [:f> - (let [scroll-enabled (reagent/atom true) - curr-scroll (atom 0)] - (fn [] - (let [sb-height (navigation/status-bar-height) - insets (safe-area/use-safe-area) - padding-top (Math/max sb-height (:top insets)) - padding-top (if platform/ios? padding-top (+ padding-top 10)) - opacity (reanimated/use-shared-value 0) - translate-y (reanimated/use-shared-value 0) - close (fn [] - (reanimated/set-shared-value opacity (reanimated/with-timing-duration 0 100)) - (rf/dispatch [:navigate-back]))] - (rn/use-effect - (fn [] - (reanimated/animate-delay opacity 1 (if platform/ios? 300 100)))) - (hooks/use-back-handler close) - [rn/view - {:style {:flex 1 - :padding-top padding-top}} - (when-not skip-background? - [reanimated/view {:style (style/background opacity)}]) - [gesture/gesture-detector - {:gesture (drag-gesture translate-y opacity scroll-enabled curr-scroll)} - [reanimated/view {:style (style/main-view translate-y)} - [rn/view {:style style/handle-container} - [rn/view {:style (style/handle)}]] - [content - {:insets insets - :close close - :scroll-enabled scroll-enabled - :on-scroll #(on-scroll % curr-scroll)}]]]])))]) + (let [scroll-enabled (reagent/atom true) + curr-scroll (atom 0)] + (fn [] + (let [insets (safe-area/get-insets) + padding-top (:top insets) + padding-top (if platform/ios? padding-top (+ padding-top 10)) + opacity (reanimated/use-shared-value 0) + translate-y (reanimated/use-shared-value 0) + close (fn [] + (reanimated/set-shared-value opacity (reanimated/with-timing-duration 0 100)) + (rf/dispatch [:navigate-back]))] + (rn/use-effect + (fn [] + (reanimated/animate-delay opacity 1 (if platform/ios? 300 100)))) + (hooks/use-back-handler close) + [rn/view + {:style {:flex 1 + :padding-top padding-top}} + (when-not skip-background? + [reanimated/view {:style (style/background opacity)}]) + [gesture/gesture-detector + {:gesture (drag-gesture translate-y opacity scroll-enabled curr-scroll)} + [reanimated/view {:style (style/main-view translate-y)} + [rn/view {:style style/handle-container} + [rn/view {:style (style/handle)}]] + [content + {:insets insets + :close close + :scroll-enabled scroll-enabled + :on-scroll #(on-scroll % curr-scroll)}]]]])))) diff --git a/src/status_im2/common/scroll_page/view.cljs b/src/status_im2/common/scroll_page/view.cljs index fed3bd8126..c8da330e36 100644 --- a/src/status_im2/common/scroll_page/view.cljs +++ b/src/status_im2/common/scroll_page/view.cljs @@ -24,7 +24,7 @@ (max minimum) (min maximum))) -(defn scroll-page-header +(defn f-scroll-page-header [scroll-height height name page-nav logo sticky-header top-nav title-colum navigate-back?] (let [input-range (if platform/ios? [-47 10] [0 10]) output-range (if platform/ios? [-208 0] [-208 -45]) @@ -88,7 +88,7 @@ sticky-header]])) -(defn display-picture +(defn f-display-picture [scroll-height cover] (let [input-range (if platform/ios? [-67 10] [0 150]) y (reanimated/use-shared-value scroll-height) @@ -115,7 +115,7 @@ sticky-header children] [:<> - [:f> scroll-page-header @scroll-height height name page-nav-right-section-buttons + [:f> f-scroll-page-header @scroll-height height name page-nav-right-section-buttons logo sticky-header top-nav title-colum navigate-back?] [rn/scroll-view {:content-container-style (style/scroll-view-container @@ -144,5 +144,5 @@ :border-radius (diff-with-max-min @scroll-height 16 0) :background-color background-color} (when cover-image - [:f> display-picture @scroll-height logo]) + [:f> f-display-picture @scroll-height logo]) children])]]))) diff --git a/src/status_im2/common/sticky_scroll_view/view.cljs b/src/status_im2/common/sticky_scroll_view/view.cljs deleted file mode 100644 index d82828c254..0000000000 --- a/src/status_im2/common/sticky_scroll_view/view.cljs +++ /dev/null @@ -1,100 +0,0 @@ -(ns status-im2.common.sticky-scroll-view.view - (:require [react-native.reanimated :as reanimated] - [react-native.core :as rn] - [react-native.platform :as platform] - [utils.worklets.scroll-view :as worklets.scroll-view] - [quo2.foundations.colors :as colors])) - -(defn sticky-item - [{:keys [height translation-y background-color]} content] - [:f> - (fn [] - [rn/view (merge {:height height} (when platform/ios? {:z-index 1})) - [reanimated/view - {:style (reanimated/apply-animations-to-style - {:transform [{:translateY translation-y}]} - {:position :absolute - :z-index (when platform/android? 1) - :top 0 - :left 0 - :right 0 - :height height - :background-color background-color})} - content]])]) - -(defn scroll-view - [{:keys [ref scroll-y blur]} & content] - [:f> - (fn [] - (let [scroll-handler (worklets.scroll-view/use-animated-scroll-handler scroll-y) - opacity (when blur - (reanimated/interpolate scroll-y - [0 (:delta blur)] - [0 1] - {:extrapolateLeft "clamp" - :extrapolateRight "extend"}))] - (into [reanimated/scroll-view - {:ref ref - :scroll-event-throttle 1 - :shows-vertical-scroll-indicator false - :contentInsetAdjustmentBehavior :never - :on-scroll scroll-handler}] - (concat - (when blur - ;bug on Android - ;https://github.com/Kureev/react-native-blur/issues/520} - [[reanimated/view - {:style (reanimated/apply-animations-to-style - {:transform [{:translateY scroll-y}] - :opacity opacity} - {:overflow (if platform/ios? :visible :hidden) - :position :absolute - :z-index 1 - :top 0 - :height (:height blur) - :right 0 - :left 0})} - [reanimated/blur-view - {:blur-amount 10 - :blur-type (if (colors/dark?) :dark :xlight) - :style {:position :absolute - :top 0 - :height (:height blur) - :right 0 - :left 0}}]]]) - content))))]) - -(defn flat-list - [{:keys [scroll-y blur header render-fn data]}] - [:f> - (fn [] - (let [scroll-handler (worklets.scroll-view/use-animated-scroll-handler scroll-y) - opacity (when blur - (reanimated/interpolate scroll-y - [0 (:delta blur)] - [0 1] - {:extrapolateLeft "clamp" - :extrapolateRight "extend"}))] - [reanimated/flat-list - {:scroll-event-throttle 1 - :shows-vertical-scroll-indicator false - :contentInsetAdjustmentBehavior :never - :data data - :render-fn render-fn - :header (if blur - [:<> - [reanimated/blur-view - {:blur-amount 10 - :blur-type :xlight - :style (reanimated/apply-animations-to-style - {:transform [{:translateY scroll-y}] - :opacity opacity} - {:z-index 1 - :position :absolute - :top 0 - :height (:height blur) - :right 0 - :left 0})}] - header] - header) - :on-scroll scroll-handler}]))]) diff --git a/src/status_im2/common/toasts/view.cljs b/src/status_im2/common/toasts/view.cljs index 3abdb935f3..309c5402f1 100644 --- a/src/status_im2/common/toasts/view.cljs +++ b/src/status_im2/common/toasts/view.cljs @@ -33,66 +33,64 @@ [quo/notification toast-opts] [quo/toast toast-opts]))) -(defn container +(defn f-container [id] (let [dismissed-locally? (reagent/atom false) close! #(rf/dispatch [:toasts/close id]) timer (reagent/atom nil) clear-timer #(utils.utils/clear-timeout @timer)] (fn [] - [:f> - (fn [] - (let [duration (or (rf/sub [:toasts/toast-cursor id :duration]) 3000) - on-dismissed (or (rf/sub [:toasts/toast-cursor id :on-dismissed]) identity) - create-timer (fn [] - (reset! timer (utils.utils/set-timeout close! duration))) - translate-y (reanimated/use-shared-value 0) - pan - (-> - (gesture/gesture-pan) - ;; remove timer on pan start - (gesture/on-start clear-timer) - (gesture/on-update - (fn [^js evt] - (let [evt-translation-y (.-translationY evt)] - (cond - ;; reset translate y on pan down - (> evt-translation-y 100) - (reanimated/animate-shared-value-with-spring translate-y - 0 - {:mass 1 - :damping 20 - :stiffness 300}) - ;; dismiss on pan up - (< evt-translation-y -30) - (do (reanimated/animate-shared-value-with-spring - translate-y - -500 - {:mass 1 :damping 20 :stiffness 300}) - (reset! dismissed-locally? true) - (close!)) - :else - (reanimated/set-shared-value translate-y - evt-translation-y))))) - (gesture/on-end (fn [_] - (when-not @dismissed-locally? - (reanimated/set-shared-value translate-y 0) - (create-timer)))))] - ;; create auto dismiss timer, clear timer when unmount or duration changed - (rn/use-effect (fn [] (create-timer) clear-timer) [duration]) - (rn/use-unmount #(on-dismissed id)) - [gesture/gesture-detector {:gesture pan} - [reanimated/view - {;; TODO: this will enable layout animation at runtime and causing flicker on android - ;; we need to resolve this and re-enable layout animation - ;; issue at https://github.com/status-im/status-mobile/issues/14752 - ;; :entering slide-in-up-animation - ;; :exiting slide-out-up-animation - ;; :layout reanimated/linear-transition - :style (reanimated/apply-animations-to-style - {:transform [{:translateY translate-y}]} - style/each-toast-container)} - [toast id]]]))]))) + (let [duration (or (rf/sub [:toasts/toast-cursor id :duration]) 3000) + on-dismissed (or (rf/sub [:toasts/toast-cursor id :on-dismissed]) identity) + create-timer (fn [] + (reset! timer (utils.utils/set-timeout close! duration))) + translate-y (reanimated/use-shared-value 0) + pan + (-> + (gesture/gesture-pan) + ;; remove timer on pan start + (gesture/on-start clear-timer) + (gesture/on-update + (fn [^js evt] + (let [evt-translation-y (.-translationY evt)] + (cond + ;; reset translate y on pan down + (> evt-translation-y 100) + (reanimated/animate-shared-value-with-spring translate-y + 0 + {:mass 1 + :damping 20 + :stiffness 300}) + ;; dismiss on pan up + (< evt-translation-y -30) + (do (reanimated/animate-shared-value-with-spring + translate-y + -500 + {:mass 1 :damping 20 :stiffness 300}) + (reset! dismissed-locally? true) + (close!)) + :else + (reanimated/set-shared-value translate-y + evt-translation-y))))) + (gesture/on-end (fn [_] + (when-not @dismissed-locally? + (reanimated/set-shared-value translate-y 0) + (create-timer)))))] + ;; create auto dismiss timer, clear timer when unmount or duration changed + (rn/use-effect (fn [] (create-timer) clear-timer) [duration]) + (rn/use-unmount #(on-dismissed id)) + [gesture/gesture-detector {:gesture pan} + [reanimated/view + {;; TODO: this will enable layout animation at runtime and causing flicker on android + ;; we need to resolve this and re-enable layout animation + ;; issue at https://github.com/status-im/status-mobile/issues/14752 + ;; :entering slide-in-up-animation + ;; :exiting slide-out-up-animation + ;; :layout reanimated/linear-transition + :style (reanimated/apply-animations-to-style + {:transform [{:translateY translate-y}]} + style/each-toast-container)} + [toast id]]])))) (defn toasts [] @@ -101,4 +99,4 @@ [rn/view {:style style/outmost-transparent-container}] (doall - (map (fn [id] ^{:key id} [container id]) toasts-ordered))])) + (map (fn [id] ^{:key id} [:f> f-container id]) toasts-ordered))])) diff --git a/src/status_im2/contexts/chat/home/view.cljs b/src/status_im2/contexts/chat/home/view.cljs index 923428fa25..9aa59c8380 100644 --- a/src/status_im2/contexts/chat/home/view.cljs +++ b/src/status_im2/contexts/chat/home/view.cljs @@ -102,32 +102,31 @@ [] (fn [] (let [pending-contact-requests (rf/sub [:activity-center/pending-contact-requests]) - selected-tab (or (rf/sub [:messages-home/selected-tab]) :tab/recent)] - [safe-area/consumer - (fn [{:keys [top]}] - [:<> - (if (= selected-tab :tab/contacts) - [contacts pending-contact-requests top] - [chats selected-tab top]) - [rn/view - {:style (style/blur-container top)} - [blur/view - {:blur-amount (if platform/ios? 20 10) - :blur-type (if (colors/dark?) :dark (if platform/ios? :light :xlight)) - :style style/blur}] - [common.home/top-nav] - [common.home/title-column - {:label (i18n/label :t/messages) - :handler #(rf/dispatch [:show-bottom-sheet - {:content home.sheet/new-chat-bottom-sheet}]) - :accessibility-label :new-chat-button}] - [quo/discover-card - {:title (i18n/label :t/invite-friends-to-status) - :description (i18n/label :t/share-invite-link)}] - [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)))}]]])]))) + selected-tab (or (rf/sub [:messages-home/selected-tab]) :tab/recent) + 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)} + [blur/view + {:blur-amount (if platform/ios? 20 10) + :blur-type (if (colors/dark?) :dark (if platform/ios? :light :xlight)) + :style style/blur}] + [common.home/top-nav] + [common.home/title-column + {:label (i18n/label :t/messages) + :handler #(rf/dispatch [:show-bottom-sheet + {:content home.sheet/new-chat-bottom-sheet}]) + :accessibility-label :new-chat-button}] + [quo/discover-card + {:title (i18n/label :t/invite-friends-to-status) + :description (i18n/label :t/share-invite-link)}] + [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)))}]]]))) diff --git a/src/status_im2/contexts/chat/menus/pinned_messages/view.cljs b/src/status_im2/contexts/chat/menus/pinned_messages/view.cljs index e15732860e..c6fae5613b 100644 --- a/src/status_im2/contexts/chat/menus/pinned_messages/view.cljs +++ b/src/status_im2/contexts/chat/menus/pinned_messages/view.cljs @@ -25,47 +25,43 @@ render-data (rf/sub [:chats/current-chat-message-list-view-context :in-pinned-view]) current-chat (rf/sub [:chat-by-id chat-id]) {:keys [community-id]} current-chat - community (rf/sub [:communities/community community-id])] - [safe-area/consumer - (fn [insets] - [:f> - (fn [] - (let [bottom-inset (:bottom insets)] - [gesture/scroll-view - {:accessibility-label :pinned-messages-menu} - [:<> - [quo/text - {:size :heading-1 - :weight :semi-bold - :style style/heading} - (i18n/label :t/pinned-messages)] - (when community - [rn/view {:style (style/heading-container)} - [rn/text {:style (style/heading-text)} (:name community)] - [quo/icon - :i/chevron-right - {:color (colors/theme-colors colors/neutral-60 colors/neutral-30) - :size 12}] - [rn/text - {:style (style/chat-name-text)} - (str "# " (:chat-name current-chat))]])] - (if (pos? (count pinned-messages)) - [rn/flat-list - {:data pinned-messages - :render-data render-data - :render-fn message-render-fn - :footer [rn/view {:style (style/list-footer bottom-inset)}] - :key-fn list-key-fn - :separator quo/separator}] - [rn/view {:style (style/no-pinned-messages-container bottom-inset)} - [rn/view {:style style/no-pinned-messages-icon} - [quo/icon :i/placeholder]] - [quo/text - {:weight :semi-bold - :style style/no-pinned-messages-text} - (i18n/label :t/no-pinned-messages)] - [quo/text {:size :paragraph-2} - (i18n/label - (if community - :t/no-pinned-messages-community-desc - :t/no-pinned-messages-desc))]])]))])])) + community (rf/sub [:communities/community community-id]) + bottom-inset (safe-area/get-bottom)] + [gesture/scroll-view + {:accessibility-label :pinned-messages-menu} + [:<> + [quo/text + {:size :heading-1 + :weight :semi-bold + :style style/heading} + (i18n/label :t/pinned-messages)] + (when community + [rn/view {:style (style/heading-container)} + [rn/text {:style (style/heading-text)} (:name community)] + [quo/icon + :i/chevron-right + {:color (colors/theme-colors colors/neutral-60 colors/neutral-30) + :size 12}] + [rn/text + {:style (style/chat-name-text)} + (str "# " (:chat-name current-chat))]])] + (if (pos? (count pinned-messages)) + [rn/flat-list + {:data pinned-messages + :render-data render-data + :render-fn message-render-fn + :footer [rn/view {:style (style/list-footer bottom-inset)}] + :key-fn list-key-fn + :separator quo/separator}] + [rn/view {:style (style/no-pinned-messages-container bottom-inset)} + [rn/view {:style style/no-pinned-messages-icon} + [quo/icon :i/placeholder]] + [quo/text + {:weight :semi-bold + :style style/no-pinned-messages-text} + (i18n/label :t/no-pinned-messages)] + [quo/text {:size :paragraph-2} + (i18n/label + (if community + :t/no-pinned-messages-community-desc + :t/no-pinned-messages-desc))]])])) diff --git a/src/status_im2/contexts/chat/messages/composer/mentions/view.cljs b/src/status_im2/contexts/chat/messages/composer/mentions/view.cljs index 74d511a832..bc0188e15a 100644 --- a/src/status_im2/contexts/chat/messages/composer/mentions/view.cljs +++ b/src/status_im2/contexts/chat/messages/composer/mentions/view.cljs @@ -9,29 +9,27 @@ [contact-list-item/contact-list-item {:on-press #(rf/dispatch [:chat.ui/select-mention text-input-ref user])} user]) -(defn mentions +(defn f-mentions [{:keys [refs suggestions max-y]} bottom-inset] - [:f> - (fn [] - (let [translate-y (reanimated/use-shared-value 0)] - (rn/use-effect - (fn [] - (reanimated/set-shared-value translate-y - (reanimated/with-timing (if (seq suggestions) 0 200))))) - [reanimated/view - {:style (reanimated/apply-animations-to-style - {:transform [{:translateY translate-y}]} - {:bottom (or bottom-inset 0) - :position :absolute - :left 0 - :right 0 - :z-index 5 - :elevation 5 - :max-height (/ max-y 2)})} - [rn/flat-list - {:keyboard-should-persist-taps :always - :data (vals suggestions) - :key-fn :key - :render-fn mention-item - :render-data (:text-input-ref refs) - :accessibility-label :mentions-list}]]))]) + (let [translate-y (reanimated/use-shared-value 0)] + (rn/use-effect + (fn [] + (reanimated/set-shared-value translate-y + (reanimated/with-timing (if (seq suggestions) 0 200))))) + [reanimated/view + {:style (reanimated/apply-animations-to-style + {:transform [{:translateY translate-y}]} + {:bottom (or bottom-inset 0) + :position :absolute + :left 0 + :right 0 + :z-index 5 + :elevation 5 + :max-height (/ max-y 2)})} + [rn/flat-list + {:keyboard-should-persist-taps :always + :data (vals suggestions) + :key-fn :key + :render-fn mention-item + :render-data (:text-input-ref refs) + :accessibility-label :mentions-list}]])) diff --git a/src/status_im2/contexts/chat/messages/composer/view.cljs b/src/status_im2/contexts/chat/messages/composer/view.cljs index 6faa5bfe58..7eb8cfd018 100644 --- a/src/status_im2/contexts/chat/messages/composer/view.cljs +++ b/src/status_im2/contexts/chat/messages/composer/view.cljs @@ -153,7 +153,7 @@ ;; `keyboard-hiding?` flag ;; 4) we store input content height in `input/input-text-content-heights` atom , we need it when chat ;; screen is reopened -(defn composer +(defn f-composer [_ _] (let [text-input-ref (rn/create-ref) send-ref (rn/create-ref) @@ -162,82 +162,80 @@ :text-input-ref text-input-ref :record-ref record-ref}] (fn [chat-id insets] - [:f> - (fn [] - (let [reply (rf/sub [:chats/reply-message]) - edit (rf/sub [:chats/edit-message]) - suggestions (rf/sub [:chat/mention-suggestions]) - images (rf/sub [:chats/sending-image]) + (let [reply (rf/sub [:chats/reply-message]) + edit (rf/sub [:chats/edit-message]) + suggestions (rf/sub [:chat/mention-suggestions]) + images (rf/sub [:chats/sending-image]) - bottom-inset (max 20 (:bottom insets)) - {window-height :height} (rn/use-window-dimensions) - {:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard) - translate-y (reanimated/use-shared-value 0) - bg-opacity (reanimated/use-shared-value 0) - bg-bottom (reanimated/use-shared-value (- window-height)) + bottom-inset (max 20 (:bottom insets)) + {window-height :height} (rn/get-window) + {:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard) + translate-y (reanimated/use-shared-value 0) + bg-opacity (reanimated/use-shared-value 0) + bg-bottom (reanimated/use-shared-value (- window-height)) - suggestions? (and (seq suggestions) - keyboard-shown - (not @keyboard-hiding?)) + suggestions? (and (seq suggestions) + keyboard-shown + (not @keyboard-hiding?)) - max-y (- window-height - (- (if (> keyboard-height 0) - keyboard-height - 360) - bottom-inset) - 46) + max-y (- window-height + (- (if (> keyboard-height 0) + keyboard-height + 360) + bottom-inset) + 46) - min-y (+ 108 - bottom-inset - (if suggestions? - (min (/ max-y 2) - (+ 16 - (* 46 (dec (count suggestions))))) - (+ 0 - (when (and - (or edit reply) - (not @input/recording-audio?)) - 38) - (when (seq images) 80)))) + min-y (+ 108 + bottom-inset + (if suggestions? + (min (/ max-y 2) + (+ 16 + (* 46 (dec (count suggestions))))) + (+ 0 + (when (and + (or edit reply) + (not @input/recording-audio?)) + 38) + (when (seq images) 80)))) - parent-height (reanimated/use-shared-value min-y) - max-parent-height (Math/abs (- max-y 110 bottom-inset)) + parent-height (reanimated/use-shared-value min-y) + max-parent-height (Math/abs (- max-y 110 bottom-inset)) - params - (prepare-params - [refs window-height translate-y bg-opacity bg-bottom min-y max-y parent-height - max-parent-height chat-id suggestions reply edit images keyboard-shown]) + params + (prepare-params + [refs window-height translate-y bg-opacity bg-bottom min-y max-y parent-height + max-parent-height chat-id suggestions reply edit images keyboard-shown]) - input-content-change (get-input-content-change params) - bottom-sheet-gesture (get-bottom-sheet-gesture params)] - (effect! params) - [reanimated/view - {:style (reanimated/apply-animations-to-style - {:height parent-height} - {})} - ;;;;input - [gesture/gesture-detector {:gesture bottom-sheet-gesture} - [reanimated/view - {:style (reanimated/apply-animations-to-style - {:transform [{:translateY translate-y}]} - (style/input-bottom-sheet window-height))} - [rn/view {:style (style/bottom-sheet-handle)}] - [edit/edit-message-auto-focus-wrapper text-input-ref edit #(clean-and-minimize params)] - [reply/reply-message-auto-focus-wrapper text-input-ref reply] - [rn/view - {:style {:height (- max-y (- min-y 38))}} - [input/text-input - {:chat-id chat-id - :on-content-size-change input-content-change - :sending-image (seq images) - :refs refs}]]]] - (if suggestions? - [mentions/mentions (select-keys params [:refs :suggestions :max-y]) bottom-inset] - [controls/view send-ref record-ref params bottom-inset chat-id images - edit #(clean-and-minimize params)]) - ;;;;black background - [reanimated/view - {:style (reanimated/apply-animations-to-style - {:opacity bg-opacity - :transform [{:translateY bg-bottom}]} - (style/bottom-sheet-background window-height))}]]))]))) + input-content-change (get-input-content-change params) + bottom-sheet-gesture (get-bottom-sheet-gesture params)] + (effect! params) + [reanimated/view + {:style (reanimated/apply-animations-to-style + {:height parent-height} + {})} + ;;;;input + [gesture/gesture-detector {:gesture bottom-sheet-gesture} + [reanimated/view + {:style (reanimated/apply-animations-to-style + {:transform [{:translateY translate-y}]} + (style/input-bottom-sheet window-height))} + [rn/view {:style (style/bottom-sheet-handle)}] + [edit/edit-message-auto-focus-wrapper text-input-ref edit #(clean-and-minimize params)] + [reply/reply-message-auto-focus-wrapper text-input-ref reply] + [rn/view + {:style {:height (- max-y (- min-y 38))}} + [input/text-input + {:chat-id chat-id + :on-content-size-change input-content-change + :sending-image (seq images) + :refs refs}]]]] + (if suggestions? + [:f> mentions/f-mentions (select-keys params [:refs :suggestions :max-y]) bottom-inset] + [controls/view send-ref record-ref params bottom-inset chat-id images + edit #(clean-and-minimize params)]) + ;;;;black background + [reanimated/view + {:style (reanimated/apply-animations-to-style + {:opacity bg-opacity + :transform [{:translateY bg-bottom}]} + (style/bottom-sheet-background window-height))}]])))) diff --git a/src/status_im2/contexts/chat/messages/content/album/view.cljs b/src/status_im2/contexts/chat/messages/content/album/view.cljs index 865d5ff88c..5f6eda9f41 100644 --- a/src/status_im2/contexts/chat/messages/content/album/view.cljs +++ b/src/status_im2/contexts/chat/messages/content/album/view.cljs @@ -20,61 +20,59 @@ (defn album-message [{:keys [albumize?] :as message} context on-long-press] - [:f> - (fn [] - (let [insets (safe-area/use-safe-area) - shared-element-id (rf/sub [:shared-element-id]) - first-image (first (:album message)) - album-style (if (> (:image-width first-image) (:image-height first-image)) - :landscape - :portrait) - images-count (count (:album message)) - ;; album images are always square, except when we have 3 images, then they must be rectangular - ;; (portrait or landscape) - portrait? (and (= images-count rectangular-style-count) (= album-style :portrait)) - text (:text (:content first-image))] - (if (and albumize? (> images-count 1)) - [:<> - (when (not= text "placeholder") - [rn/view {:style {:margin-bottom 10}} [text/text-content first-image context]]) - [rn/view - {:style (style/album-container portrait?)} - (map-indexed - (fn [index item] - (let [images-size-key (if (< images-count constants/max-album-photos) - images-count - :default) - size (get-in constants/album-image-sizes [images-size-key index]) - dimensions (if (not= images-count rectangular-style-count) - {:width size :height size} - (find-size size album-style))] - [rn/touchable-opacity - {:key (:message-id item) - :active-opacity 1 - :on-long-press #(on-long-press message context) - :on-press #(rf/dispatch [:chat.ui/navigate-to-lightbox - (:message-id item) - {:messages (:album message) - :index index - :insets insets}])} - [fast-image/fast-image - {:style (style/image dimensions index portrait? images-count) - :source {:uri (:image (:content item))} - :native-ID (when (and (= shared-element-id (:message-id item)) - (< index constants/max-album-photos)) - :shared-element)}] - (when (and (> images-count constants/max-album-photos) - (= index (- constants/max-album-photos 1))) - [rn/view - {:style style/overlay} - [quo/text - {:weight :bold - :size :heading-2 - :style {:color colors/white}} - (str "+" (- images-count (dec constants/max-album-photos)))]])])) - (:album message))]] - [:<> - (map-indexed - (fn [index item] - [image/image-message index item context #(on-long-press message context)]) - (:album message))])))]) + (let [insets (safe-area/get-insets) + shared-element-id (rf/sub [:shared-element-id]) + first-image (first (:album message)) + album-style (if (> (:image-width first-image) (:image-height first-image)) + :landscape + :portrait) + images-count (count (:album message)) + ;; album images are always square, except when we have 3 images, then they must be rectangular + ;; (portrait or landscape) + portrait? (and (= images-count rectangular-style-count) (= album-style :portrait)) + text (:text (:content first-image))] + (if (and albumize? (> images-count 1)) + [:<> + (when (not= text "placeholder") + [rn/view {:style {:margin-bottom 10}} [text/text-content first-image context]]) + [rn/view + {:style (style/album-container portrait?)} + (map-indexed + (fn [index item] + (let [images-size-key (if (< images-count constants/max-album-photos) + images-count + :default) + size (get-in constants/album-image-sizes [images-size-key index]) + dimensions (if (not= images-count rectangular-style-count) + {:width size :height size} + (find-size size album-style))] + [rn/touchable-opacity + {:key (:message-id item) + :active-opacity 1 + :on-long-press #(on-long-press message context) + :on-press #(rf/dispatch [:chat.ui/navigate-to-lightbox + (:message-id item) + {:messages (:album message) + :index index + :insets insets}])} + [fast-image/fast-image + {:style (style/image dimensions index portrait? images-count) + :source {:uri (:image (:content item))} + :native-ID (when (and (= shared-element-id (:message-id item)) + (< index constants/max-album-photos)) + :shared-element)}] + (when (and (> images-count constants/max-album-photos) + (= index (- constants/max-album-photos 1))) + [rn/view + {:style style/overlay} + [quo/text + {:weight :bold + :size :heading-2 + :style {:color colors/white}} + (str "+" (- images-count (dec constants/max-album-photos)))]])])) + (:album message))]] + [:<> + (map-indexed + (fn [index item] + [image/image-message index item context #(on-long-press message context)]) + (:album message))]))) diff --git a/src/status_im2/contexts/chat/messages/content/image/view.cljs b/src/status_im2/contexts/chat/messages/content/image/view.cljs index c598994300..ff6c0a2762 100644 --- a/src/status_im2/contexts/chat/messages/content/image/view.cljs +++ b/src/status_im2/contexts/chat/messages/content/image/view.cljs @@ -15,26 +15,24 @@ (defn image-message [index {:keys [content image-width image-height message-id] :as message} context on-long-press] - [:f> - (fn [] - (let [insets (safe-area/use-safe-area) - dimensions (calculate-dimensions (or image-width 1000) (or image-height 1000)) - text (:text content)] - (fn [] - (let [shared-element-id (rf/sub [:shared-element-id])] - [rn/touchable-opacity - {:active-opacity 1 - :key message-id - :style {:margin-top (when (pos? index) 10)} - :on-long-press on-long-press - :on-press #(rf/dispatch [:chat.ui/navigate-to-lightbox - message-id - {:messages [message] - :index 0 - :insets insets}])} - (when (and (not= text "placeholder") (= index 0)) - [rn/view {:style {:margin-bottom 10}} [text/text-content message context]]) - [fast-image/fast-image - {:source {:uri (:image content)} - :style (merge dimensions {:border-radius 12}) - :native-ID (when (= shared-element-id message-id) :shared-element)}]]))))]) + (let [insets (safe-area/get-insets) + dimensions (calculate-dimensions (or image-width 1000) (or image-height 1000)) + text (:text content)] + (fn [] + (let [shared-element-id (rf/sub [:shared-element-id])] + [rn/touchable-opacity + {:active-opacity 1 + :key message-id + :style {:margin-top (when (pos? index) 10)} + :on-long-press on-long-press + :on-press #(rf/dispatch [:chat.ui/navigate-to-lightbox + message-id + {:messages [message] + :index 0 + :insets insets}])} + (when (and (not= text "placeholder") (= index 0)) + [rn/view {:style {:margin-bottom 10}} [text/text-content message context]]) + [fast-image/fast-image + {:source {:uri (:image content)} + :style (merge dimensions {:border-radius 12}) + :native-ID (when (= shared-element-id message-id) :shared-element)}]])))) diff --git a/src/status_im2/contexts/chat/messages/view.cljs b/src/status_im2/contexts/chat/messages/view.cljs index 929ce4fe6a..347b81f2bb 100644 --- a/src/status_im2/contexts/chat/messages/view.cljs +++ b/src/status_im2/contexts/chat/messages/view.cljs @@ -68,18 +68,17 @@ [] (let [;;NOTE: we want to react only on these fields, do not use full chat map here {:keys [chat-id contact-request-state group-chat able-to-send-message?] :as chat} - (rf/sub [:chats/current-chat-chat-view])] - [safe-area/consumer - (fn [insets] - [rn/keyboard-avoiding-view - {:style {:position :relative :flex 1} - :keyboardVerticalOffset (- (:bottom insets))} - [page-nav] - [pin.banner/banner chat-id] - [messages.list/messages-list chat insets] - (if-not able-to-send-message? - [contact-requests.bottom-drawer/view chat-id contact-request-state group-chat] - [composer/composer chat-id insets])])])) + (rf/sub [:chats/current-chat-chat-view]) + insets (safe-area/get-insets)] + [rn/keyboard-avoiding-view + {:style {:position :relative :flex 1} + :keyboardVerticalOffset (- (:bottom insets))} + [page-nav] + [pin.banner/banner chat-id] + [messages.list/messages-list chat insets] + (if-not able-to-send-message? + [contact-requests.bottom-drawer/view chat-id contact-request-state group-chat] + [:f> composer/f-composer chat-id insets])])) (defn chat [] diff --git a/src/status_im2/contexts/chat/photo_selector/album_selector/view.cljs b/src/status_im2/contexts/chat/photo_selector/album_selector/view.cljs index fce76aa3e1..3f5e2f7d08 100644 --- a/src/status_im2/contexts/chat/photo_selector/album_selector/view.cljs +++ b/src/status_im2/contexts/chat/photo_selector/album_selector/view.cljs @@ -51,26 +51,22 @@ (str (:title item) index)) (defn album-selector - [{:keys [scroll-enabled on-scroll]}] - [:f> - (fn [] - (let [albums (rf/sub [:camera-roll/albums]) - selected-album (or (rf/sub [:camera-roll/selected-album]) (i18n/label :t/recent))] - (rn/use-effect-once - (fn [] - (rf/dispatch [:chat.ui/camera-roll-get-albums]) - js/undefined)) - [rn/view {:style {:padding-top 20}} - [album-title false] - [gesture/section-list - {:data albums - :render-fn album - :render-data selected-album - :sections albums - :sticky-section-headers-enabled false - :render-section-header-fn section-header - :style {:margin-top 12} - :content-container-style {:padding-bottom 40} - :key-fn key-fn - :scroll-enabled @scroll-enabled - :on-scroll on-scroll}]]))]) + [{:keys [on-scroll]}] + (rf/dispatch [:chat.ui/camera-roll-get-albums]) + (fn [{:keys [scroll-enabled]}] + (let [albums (rf/sub [:camera-roll/albums]) + selected-album (or (rf/sub [:camera-roll/selected-album]) (i18n/label :t/recent))] + [rn/view {:style {:padding-top 20}} + [album-title false] + [gesture/section-list + {:data albums + :render-fn album + :render-data selected-album + :sections albums + :sticky-section-headers-enabled false + :render-section-header-fn section-header + :style {:margin-top 12} + :content-container-style {:padding-bottom 40} + :key-fn key-fn + :scroll-enabled @scroll-enabled + :on-scroll on-scroll}]]))) diff --git a/src/status_im2/contexts/communities/home/view.cljs b/src/status_im2/contexts/communities/home/view.cljs index 33644ac169..acd93a9963 100644 --- a/src/status_im2/contexts/communities/home/view.cljs +++ b/src/status_im2/contexts/communities/home/view.cljs @@ -40,35 +40,34 @@ selected-items (case @selected-tab :joined joined :pending pending - :opened opened)] - [safe-area/consumer - (fn [{:keys [top]}] - [:<> - [rn/flat-list - {:key-fn :id - :content-inset-adjustment-behavior :never - :header [rn/view {:height (+ 245 top)}] - :render-fn item-render - :data selected-items}] - [rn/view - {:style (style/blur-container top)} - [blur/view - {:blur-amount (if platform/ios? 20 10) - :blur-type (if (colors/dark?) :dark (if platform/ios? :light :xlight)) - :style style/blur}] - [common.home/top-nav] - [common.home/title-column - {:label (i18n/label :t/communities) - :handler #(rf/dispatch [:bottom-sheet/show-sheet-old :add-new {}]) - :accessibility-label :new-chat-button}] - [quo/discover-card - {:on-press #(rf/dispatch [:navigate-to :discover-communities]) - :title (i18n/label :t/discover) - :description (i18n/label :t/whats-trending) - :accessibility-label :communities-home-discover-card}] - [quo/tabs - {:size 32 - :style style/tabs - :on-change #(reset! selected-tab %) - :default-active @selected-tab - :data tabs-data}]]])])))) + :opened opened) + top (safe-area/get-top)] + [:<> + [rn/flat-list + {:key-fn :id + :content-inset-adjustment-behavior :never + :header [rn/view {:height (+ 245 top)}] + :render-fn item-render + :data selected-items}] + [rn/view + {:style (style/blur-container top)} + [blur/view + {:blur-amount (if platform/ios? 20 10) + :blur-type (if (colors/dark?) :dark (if platform/ios? :light :xlight)) + :style style/blur}] + [common.home/top-nav] + [common.home/title-column + {:label (i18n/label :t/communities) + :handler #(rf/dispatch [:bottom-sheet/show-sheet-old :add-new {}]) + :accessibility-label :new-chat-button}] + [quo/discover-card + {:on-press #(rf/dispatch [:navigate-to :discover-communities]) + :title (i18n/label :t/discover) + :description (i18n/label :t/whats-trending) + :accessibility-label :communities-home-discover-card}] + [quo/tabs + {:size 32 + :style style/tabs + :on-change #(reset! selected-tab %) + :default-active @selected-tab + :data tabs-data}]]])))) diff --git a/src/status_im2/contexts/onboarding/common/background/view.cljs b/src/status_im2/contexts/onboarding/common/background/view.cljs index 94a2dbd09d..b372b78b22 100644 --- a/src/status_im2/contexts/onboarding/common/background/view.cljs +++ b/src/status_im2/contexts/onboarding/common/background/view.cljs @@ -5,19 +5,21 @@ [status-im2.contexts.onboarding.common.background.style :as style] [status-im2.contexts.onboarding.common.carousel.animation :as carousel.animation])) +(defn f-view + [dark-overlay?] + (let [animate? (not dark-overlay?)] + (when animate? (carousel.animation/initialize-animation)) + [rn/view + {:style style/background-container} + [:f> carousel/f-view animate?] + (when dark-overlay? + [blur/view + {:style style/background-blur-overlay + :blur-amount 30 + :blur-radius 25 + :blur-type :transparent + :overlay-color :transparent}])])) + (defn view [dark-overlay?] - [:f> - (fn [] - (let [animate? (not dark-overlay?)] - (when animate? (carousel.animation/initialize-animation)) - [rn/view - {:style style/background-container} - [carousel/view animate?] - (when dark-overlay? - [blur/view - {:style style/background-blur-overlay - :blur-amount 30 - :blur-radius 25 - :blur-type :transparent - :overlay-color :transparent}])]))]) + [:f> f-view dark-overlay?]) diff --git a/src/status_im2/contexts/onboarding/common/carousel/view.cljs b/src/status_im2/contexts/onboarding/common/carousel/view.cljs index 636774e946..c23e6bb421 100644 --- a/src/status_im2/contexts/onboarding/common/carousel/view.cljs +++ b/src/status_im2/contexts/onboarding/common/carousel/view.cljs @@ -53,46 +53,41 @@ [rn/view {:style (style/progress-bar-item static? false)}] [rn/view {:style (style/progress-bar-item static? true)}]]) -(defn dynamic-progress-bar +(defn f-dynamic-progress-bar [progress-bar-width animate?] - [:f> - (fn [] - (let [width (animation/dynamic-progress-bar-width progress-bar-width animate?) - container-view (if animate? reanimated/view rn/view)] - [container-view {:style (style/dynamic-progress-bar width animate?)} - [progress-bar - {:static? false - :progress-bar-width progress-bar-width}]]))]) + (let [width (animation/dynamic-progress-bar-width progress-bar-width animate?) + container-view (if animate? reanimated/view rn/view)] + [container-view {:style (style/dynamic-progress-bar width animate?)} + [progress-bar + {:static? false + :progress-bar-width progress-bar-width}]])) -(defn view +(defn f-view [animate?] - [:f> - (fn [] - (let [window-width (rf/sub [:dimensions/window-width]) - view-id (rf/sub [:view-id]) - status-bar-height (:status-bar-height @navigation/constants) - progress-bar-width (- window-width 40) - carousel-left (animation/carousel-left-position window-width animate?) - container-view (if animate? reanimated/view rn/view)] - (when animate? - (rn/use-effect - (fn [] - (reanimated/set-shared-value @animation/paused (not= view-id :intro))) - [view-id])) - [:<> - [container-view {:style (style/carousel-container carousel-left animate?)} - (for [index (range 2)] - ^{:key index} - [content-view - {:window-width window-width - :status-bar-height status-bar-height - :index index}])] - [rn/view - {:style (style/progress-bar-container - progress-bar-width - status-bar-height)} - [progress-bar - {:static? true - :progress-bar-width progress-bar-width}] - [dynamic-progress-bar progress-bar-width animate?]]]))]) - + (let [window-width (rf/sub [:dimensions/window-width]) + view-id (rf/sub [:view-id]) + status-bar-height (:status-bar-height @navigation/constants) + progress-bar-width (- window-width 40) + carousel-left (animation/carousel-left-position window-width animate?) + container-view (if animate? reanimated/view rn/view)] + (when animate? + (rn/use-effect + (fn [] + (reanimated/set-shared-value @animation/paused (not= view-id :intro))) + [view-id])) + [:<> + [container-view {:style (style/carousel-container carousel-left animate?)} + (for [index (range 2)] + ^{:key index} + [content-view + {:window-width window-width + :status-bar-height status-bar-height + :index index}])] + [rn/view + {:style (style/progress-bar-container + progress-bar-width + status-bar-height)} + [progress-bar + {:static? true + :progress-bar-width progress-bar-width}] + [:f> f-dynamic-progress-bar progress-bar-width animate?]]])) diff --git a/src/status_im2/contexts/onboarding/create_password/view.cljs b/src/status_im2/contexts/onboarding/create_password/view.cljs index c70b7400ba..3e542088d2 100644 --- a/src/status_im2/contexts/onboarding/create_password/view.cljs +++ b/src/status_im2/contexts/onboarding/create_password/view.cljs @@ -186,21 +186,20 @@ (defn create-password [] - [:f> - (let [scroll-view-ref (atom nil) - scroll-to-end-fn #(js/setTimeout ^js/Function (.-scrollToEnd @scroll-view-ref) 250)] - (fn [] - (let [{:keys [top]} (safe-area/use-safe-area)] - [:<> - [background/view true] - [rn/scroll-view - {:ref #(reset! scroll-view-ref %) - :style style/overlay - :content-container-style style/content-style} - [navigation-bar/navigation-bar - {:top top - :right-section-buttons [{:type :blur-bg - :icon :i/info - :icon-override-theme :dark - :on-press #(js/alert "Info pressed")}]}] - [password-form {:scroll-to-end-fn scroll-to-end-fn}]]])))]) + (let [scroll-view-ref (atom nil) + scroll-to-end-fn #(js/setTimeout ^js/Function (.-scrollToEnd @scroll-view-ref) 250)] + (fn [] + (let [{:keys [top]} (safe-area/get-insets)] + [:<> + [background/view true] + [rn/scroll-view + {:ref #(reset! scroll-view-ref %) + :style style/overlay + :content-container-style style/content-style} + [navigation-bar/navigation-bar + {:top top + :right-section-buttons [{:type :blur-bg + :icon :i/info + :icon-override-theme :dark + :on-press #(js/alert "Info pressed")}]}] + [password-form {:scroll-to-end-fn scroll-to-end-fn}]]])))) diff --git a/src/status_im2/contexts/onboarding/create_profile/view.cljs b/src/status_im2/contexts/onboarding/create_profile/view.cljs index bd6634f952..539f82c472 100644 --- a/src/status_im2/contexts/onboarding/create_profile/view.cljs +++ b/src/status_im2/contexts/onboarding/create_profile/view.cljs @@ -55,107 +55,103 @@ [rn/view {:style style/view-button-container} children])) -(defn page +(defn- f-page [{:keys [onboarding-profile-data navigation-bar-top]}] - [:f> - (fn [] - (let [{:keys [image-path display-name color]} onboarding-profile-data - full-name (reagent/atom display-name) - keyboard-shown? (reagent/atom false) - validation-msg (reagent/atom (validation-message @full-name)) - on-change-text (fn [s] - (reset! validation-msg (validation-message s)) - (reset! full-name (string/trim s))) - custom-color (reagent/atom (or color c/profile-default-color)) - profile-pic (reagent/atom image-path) - on-change-profile-pic #(reset! profile-pic %) - on-change #(reset! custom-color %)] - (fn [] - (rn/use-effect - (let [will-show-listener (oops/ocall rn/keyboard - "addListener" - "keyboardWillShow" - #(swap! keyboard-shown? (fn [] true))) - will-hide-listener (oops/ocall rn/keyboard - "addListener" - "keyboardWillHide" - #(swap! keyboard-shown? (fn [] false)))] - (fn [] - (fn [] - (oops/ocall will-show-listener "remove") - (oops/ocall will-hide-listener "remove")))) - []) - [rn/view {:style style/page-container} - [navigation-bar/navigation-bar {:top navigation-bar-top}] - [rn/scroll-view - {:keyboard-should-persist-taps :always - :content-container-style {:flex-grow 1}} - [rn/view {:style style/page-container} - [rn/view - {:style style/content-container} - [quo/text - {:size :heading-1 - :weight :semi-bold - :style style/title} (i18n/label :t/create-profile)] - [rn/view - {:style style/input-container} - [rn/view - {:style style/profile-input-container} - [quo/profile-input - {:customization-color @custom-color - :placeholder (i18n/label :t/your-name) - :on-press (fn [] - (rf/dispatch [:dismiss-keyboard]) - (rf/dispatch - [:show-bottom-sheet - {:override-theme :dark - :content - (fn [] - [method-menu/view on-change-profile-pic])}])) - :image-picker-props {:profile-picture @profile-pic - :full-name @full-name} - :title-input-props {:default-value @full-name - :max-length c/profile-name-max-length - :on-change-text on-change-text}}]] - (when @validation-msg - [quo/info-message - {:type :error - :size :default - :icon :i/info - :style style/info-message} - @validation-msg]) - [quo/text - {:size :paragraph-2 - :style style/color-title} - (i18n/label :t/accent-colour)] - [quo/color-picker - {:blur? true - :default-selected? :blue - :selected @custom-color - :on-change on-change}]]]]] - [rn/keyboard-avoiding-view {} - [button-container @keyboard-shown? - [quo/button - {:accessibility-label :submit-create-profile-button - :type :primary - :override-background-color (colors/custom-color @custom-color 60) - :on-press (fn [] - (rf/dispatch [:onboarding-2/profile-data-set - {:image-path @profile-pic - :display-name @full-name - :color @custom-color}])) - :style style/continue-button - :disabled (or (not (seq @full-name)) @validation-msg)} - (i18n/label :t/continue)]]]])))]) + (let [{:keys [image-path display-name color]} onboarding-profile-data + full-name (reagent/atom display-name) + keyboard-shown? (reagent/atom false) + validation-msg (reagent/atom (validation-message @full-name)) + on-change-text (fn [s] + (reset! validation-msg (validation-message s)) + (reset! full-name (string/trim s))) + custom-color (reagent/atom (or color c/profile-default-color)) + profile-pic (reagent/atom image-path) + on-change-profile-pic #(reset! profile-pic %) + on-change #(reset! custom-color %)] + (fn [] + (rn/use-effect + (let [will-show-listener (oops/ocall rn/keyboard + "addListener" + "keyboardWillShow" + #(swap! keyboard-shown? (fn [] true))) + will-hide-listener (oops/ocall rn/keyboard + "addListener" + "keyboardWillHide" + #(swap! keyboard-shown? (fn [] false)))] + (fn [] + (fn [] + (oops/ocall will-show-listener "remove") + (oops/ocall will-hide-listener "remove")))) + []) + [rn/view {:style style/page-container} + [navigation-bar/navigation-bar {:top navigation-bar-top}] + [rn/scroll-view + {:keyboard-should-persist-taps :always + :content-container-style {:flex-grow 1}} + [rn/view {:style style/page-container} + [rn/view + {:style style/content-container} + [quo/text + {:size :heading-1 + :weight :semi-bold + :style style/title} (i18n/label :t/create-profile)] + [rn/view + {:style style/input-container} + [rn/view + {:style style/profile-input-container} + [quo/profile-input + {:customization-color @custom-color + :placeholder (i18n/label :t/your-name) + :on-press (fn [] + (rf/dispatch [:dismiss-keyboard]) + (rf/dispatch + [:show-bottom-sheet + {:override-theme :dark + :content + (fn [] + [method-menu/view on-change-profile-pic])}])) + :image-picker-props {:profile-picture @profile-pic + :full-name @full-name} + :title-input-props {:default-value @full-name + :max-length c/profile-name-max-length + :on-change-text on-change-text}}]] + (when @validation-msg + [quo/info-message + {:type :error + :size :default + :icon :i/info + :style style/info-message} + @validation-msg]) + [quo/text + {:size :paragraph-2 + :style style/color-title} + (i18n/label :t/accent-colour)] + [quo/color-picker + {:blur? true + :default-selected? :blue + :selected @custom-color + :on-change on-change}]]]]] + [rn/keyboard-avoiding-view {} + [button-container @keyboard-shown? + [quo/button + {:accessibility-label :submit-create-profile-button + :type :primary + :override-background-color (colors/custom-color @custom-color 60) + :on-press (fn [] + (rf/dispatch [:onboarding-2/profile-data-set + {:image-path @profile-pic + :display-name @full-name + :color @custom-color}])) + :style style/continue-button + :disabled (or (not (seq @full-name)) @validation-msg)} + (i18n/label :t/continue)]]]]))) (defn create-profile [] - [:f> - (fn [] - (let [{:keys [top]} (safe-area/use-safe-area) - onboarding-profile-data (rf/sub [:onboarding-2/profile])] - [:<> - [background/view true] - [page - {:navigation-bar-top top - :onboarding-profile-data onboarding-profile-data}]]))]) + (let [{:keys [top]} (safe-area/get-insets) + onboarding-profile-data (rf/sub [:onboarding-2/profile])] + [:<> + [background/view true] + [:f> f-page + {:navigation-bar-top top + :onboarding-profile-data onboarding-profile-data}]])) diff --git a/src/status_im2/contexts/onboarding/enable_biometrics/view.cljs b/src/status_im2/contexts/onboarding/enable_biometrics/view.cljs index d0c5f6211f..b951defc46 100644 --- a/src/status_im2/contexts/onboarding/enable_biometrics/view.cljs +++ b/src/status_im2/contexts/onboarding/enable_biometrics/view.cljs @@ -38,13 +38,11 @@ (defn enable-biometrics [] - [:f> - (fn [] - (let [insets (safe-area/use-safe-area)] - [rn/view {:style (style/page-container insets)} - [navigation-bar/navigation-bar {:disable-back-button? true}] - [page-title] - [rn/view {:style style/page-illustration} - [quo/text - "Illustration here"]] - [enable-biometrics-buttons {:insets insets}]]))]) + (let [insets (safe-area/get-insets)] + [rn/view {:style (style/page-container insets)} + [navigation-bar/navigation-bar {:disable-back-button? true}] + [page-title] + [rn/view {:style style/page-illustration} + [quo/text + "Illustration here"]] + [enable-biometrics-buttons {:insets insets}]])) diff --git a/src/status_im2/contexts/onboarding/enable_notifications/view.cljs b/src/status_im2/contexts/onboarding/enable_notifications/view.cljs index e496d9b573..7d989ee89b 100644 --- a/src/status_im2/contexts/onboarding/enable_notifications/view.cljs +++ b/src/status_im2/contexts/onboarding/enable_notifications/view.cljs @@ -46,14 +46,12 @@ (defn enable-notifications [] - [:f> - (fn [] - (let [insets (safe-area/use-safe-area)] - [rn/view {:style (style/page-container insets)} - [background/view true] - [navigation-bar/navigation-bar {:disable-back-button? true}] - [page-title] - [rn/view {:style style/page-illustration} - [quo/text - "Illustration here"]] - [enable-notification-buttons {:insets insets}]]))]) + (let [insets (safe-area/get-insets)] + [rn/view {:style (style/page-container insets)} + [background/view true] + [navigation-bar/navigation-bar {:disable-back-button? true}] + [page-title] + [rn/view {:style style/page-illustration} + [quo/text + "Illustration here"]] + [enable-notification-buttons {:insets insets}]])) diff --git a/src/status_im2/contexts/onboarding/enter_seed_phrase/view.cljs b/src/status_im2/contexts/onboarding/enter_seed_phrase/view.cljs index ce6ca04a32..a03fed0628 100644 --- a/src/status_im2/contexts/onboarding/enter_seed_phrase/view.cljs +++ b/src/status_im2/contexts/onboarding/enter_seed_phrase/view.cljs @@ -65,9 +65,7 @@ (defn enter-seed-phrase [] - [:f> - (fn [] - (let [{:keys [top]} (safe-area/use-safe-area)] - [rn/view {:style {:flex 1}} - [background/view true] - [page {:navigation-bar-top top}]]))]) + (let [{:keys [top]} (safe-area/get-insets)] + [rn/view {:style {:flex 1}} + [background/view true] + [page {:navigation-bar-top top}]])) diff --git a/src/status_im2/contexts/onboarding/generating_keys/view.cljs b/src/status_im2/contexts/onboarding/generating_keys/view.cljs index 43b7117c90..b630fbc668 100644 --- a/src/status_im2/contexts/onboarding/generating_keys/view.cljs +++ b/src/status_im2/contexts/onboarding/generating_keys/view.cljs @@ -21,9 +21,7 @@ (defn generating-keys [] - [:f> - (fn [] - (let [{:keys [top]} (safe-area/use-safe-area)] - [rn/view {:style {:flex 1}} - [background/view true] - [page {:navigation-bar-top top}]]))]) \ No newline at end of file + (let [{:keys [top]} (safe-area/get-insets)] + [rn/view {:style {:flex 1}} + [background/view true] + [page {:navigation-bar-top top}]])) diff --git a/src/status_im2/contexts/onboarding/new_to_status/view.cljs b/src/status_im2/contexts/onboarding/new_to_status/view.cljs index 0b03afd4d7..a963e3dd73 100644 --- a/src/status_im2/contexts/onboarding/new_to_status/view.cljs +++ b/src/status_im2/contexts/onboarding/new_to_status/view.cljs @@ -56,16 +56,14 @@ (defn new-to-status [] - [:f> - (fn [] - (let [{:keys [top]} (safe-area/use-safe-area)] - [:<> - [background/view true] - [rn/view {:style style/content-container} - [navigation-bar/navigation-bar - {:top top - :right-section-buttons [{:type :blur-bg - :icon :i/info - :icon-override-theme :dark - :on-press #(js/alert "Info pressed")}]}] - [sign-in-options]]]))]) + (let [{:keys [top]} (safe-area/get-insets)] + [:<> + [background/view true] + [rn/view {:style style/content-container} + [navigation-bar/navigation-bar + {:top top + :right-section-buttons [{:type :blur-bg + :icon :i/info + :icon-override-theme :dark + :on-press #(js/alert "Info pressed")}]}] + [sign-in-options]]])) diff --git a/src/status_im2/contexts/onboarding/sign_in/view.cljs b/src/status_im2/contexts/onboarding/sign_in/view.cljs index 577997ffb3..b956426ec8 100644 --- a/src/status_im2/contexts/onboarding/sign_in/view.cljs +++ b/src/status_im2/contexts/onboarding/sign_in/view.cljs @@ -86,19 +86,18 @@ (defn- qr-scan-hole-area [qr-view-finder] - (let [status-bar-height (rn/status-bar-height)] - [rn/view - {:style style/qr-view-finder - :on-layout (fn [event] - (let [layout (transforms/js->clj (oops/oget event "nativeEvent.layout")) - width (:width layout) - y (if platform/android? - (+ status-bar-height (:y layout)) - (:y layout)) - view-finder (-> layout - (assoc :height width) - (assoc :y y))] - (reset! qr-view-finder view-finder)))}])) + [rn/view + {:style style/qr-view-finder + :on-layout (fn [event] + (let [layout (transforms/js->clj (oops/oget event "nativeEvent.layout")) + width (:width layout) + y (if platform/android? + (+ (safe-area/get-top) (:y layout)) + (:y layout)) + view-finder (-> layout + (assoc :height width) + (assoc :y y))] + (reset! qr-view-finder view-finder)))}]) (defn- border @@ -168,9 +167,12 @@ :override-theme :light :text (i18n/label :t/error-this-is-not-a-sync-qr-code)}])))) -(defn view +(defn f-view [] - (let [active-tab (reagent/atom 1) + (let [camera-ref (atom nil) + read-qr-once? (atom false) + insets (safe-area/get-insets) + active-tab (reagent/atom 1) qr-view-finder (reagent/atom {}) {:keys [height width]} (rf/sub [:dimensions/window]) request-camera-permission (fn [] @@ -185,55 +187,55 @@ :override-theme :light :text (i18n/label :t/camera-permission-denied)}])}]))] - [:f> - (fn [] - (let [insets (safe-area/use-safe-area) - camera-ref (atom nil) - read-qr-once? (atom false) - holes (merge @qr-view-finder {:borderRadius 16}) - scan-qr-code-tab? (= @active-tab 1) - show-camera? (and scan-qr-code-tab? @camera-permission-granted?) - show-holes? (and show-camera? - (boolean (not-empty @qr-view-finder))) - on-read-code (fn [data] - (when-not @read-qr-once? - (reset! read-qr-once? true) - (js/setTimeout (fn [] - (reset! read-qr-once? false)) - 3000) - (check-qr-code-data data))) - hole-view-wrapper (if show-camera? - [hole-view/hole-view - {:style style/absolute-fill - :holes (if show-holes? - [holes] - [])}] - [:<>])] - (rn/use-effect - (fn [] - (when-not @camera-permission-granted? - (permissions/permission-granted? :camera - #(reset! camera-permission-granted? %) - #(reset! camera-permission-granted? false))))) - [rn/view {:style (style/root-container (:top insets))} - (if show-camera? - [camera-kit/camera - {:ref #(reset! camera-ref %) - :style (merge style/absolute-fill {:height height :width width}) - :camera-options {:zoomMode :off} - :scan-barcode true - :on-read-code on-read-code}] - [background/view true]) - (conj hole-view-wrapper - [blur/view - {:style style/absolute-fill - :overlay-color colors/neutral-80-opa-80 - :blur-type :dark - :blur-amount (if platform/ios? 15 5)}]) - [header active-tab read-qr-once?] - (case @active-tab - 1 [scan-qr-code-tab qr-view-finder request-camera-permission] - 2 [enter-sync-code-tab] - nil) - [rn/view {:style style/flex-spacer}] - [bottom-view insets]]))])) + (fn [] + (let [holes (merge @qr-view-finder {:borderRadius 16}) + scan-qr-code-tab? (= @active-tab 1) + show-camera? (and scan-qr-code-tab? @camera-permission-granted?) + show-holes? (and show-camera? + (boolean (not-empty @qr-view-finder))) + on-read-code (fn [data] + (when-not @read-qr-once? + (reset! read-qr-once? true) + (js/setTimeout (fn [] + (reset! read-qr-once? false)) + 3000) + (check-qr-code-data data))) + hole-view-wrapper (if show-camera? + [hole-view/hole-view + {:style style/absolute-fill + :holes (if show-holes? + [holes] + [])}] + [:<>])] + (rn/use-effect + (fn [] + (when-not @camera-permission-granted? + (permissions/permission-granted? :camera + #(reset! camera-permission-granted? %) + #(reset! camera-permission-granted? false))))) + [rn/view {:style (style/root-container (:top insets))} + (if show-camera? + [camera-kit/camera + {:ref #(reset! camera-ref %) + :style (merge style/absolute-fill {:height height :width width}) + :camera-options {:zoomMode :off} + :scan-barcode true + :on-read-code on-read-code}] + [background/view true]) + (conj hole-view-wrapper + [blur/view + {:style style/absolute-fill + :overlay-color colors/neutral-80-opa-80 + :blur-type :dark + :blur-amount (if platform/ios? 15 5)}]) + [header active-tab read-qr-once?] + (case @active-tab + 1 [scan-qr-code-tab qr-view-finder request-camera-permission] + 2 [enter-sync-code-tab] + nil) + [rn/view {:style style/flex-spacer}] + [bottom-view insets]])))) + +(defn view + [] + [:f> f-view]) diff --git a/src/status_im2/contexts/onboarding/syncing/syncing_devices/view.cljs b/src/status_im2/contexts/onboarding/syncing/syncing_devices/view.cljs index 93f3154630..b300e936b0 100644 --- a/src/status_im2/contexts/onboarding/syncing/syncing_devices/view.cljs +++ b/src/status_im2/contexts/onboarding/syncing/syncing_devices/view.cljs @@ -32,9 +32,6 @@ (defn syncing-devices [] - (fn [] - [safe-area/consumer - (fn [{:keys [top]}] - [rn/view {:style {:flex 1}} - [background/view true] - [page {:navigation-bar-top top}]])])) + [rn/view {:style {:flex 1}} + [background/view true] + [page {:navigation-bar-top (safe-area/get-top)}]]) diff --git a/src/status_im2/contexts/onboarding/welcome/view.cljs b/src/status_im2/contexts/onboarding/welcome/view.cljs index 2ab20392fa..5faa8f658b 100644 --- a/src/status_im2/contexts/onboarding/welcome/view.cljs +++ b/src/status_im2/contexts/onboarding/welcome/view.cljs @@ -35,20 +35,19 @@ (defn view [] - (let [profile-color (:color (rf/sub [:onboarding-2/profile]))] - [safe-area/consumer - (fn [insets] - [rn/view {:style (style/page-container insets)} - [background/view true] - [navigation-bar :enable-notifications] - [page-title] - [rn/view {:style style/page-illustration} - [quo/text - "Illustration here"]] - [rn/view {:style (style/buttons insets)} - [quo/button - {:on-press #(rf/dispatch [:init-root :shell-stack]) - :type :primary - :accessibility-label :welcome-button - :override-background-color (colors/custom-color profile-color 60)} - (i18n/label :t/start-using-status)]]])])) \ No newline at end of file + (let [profile-color (:color (rf/sub [:onboarding-2/profile])) + insets (safe-area/get-insets)] + [rn/view {:style (style/page-container insets)} + [background/view true] + [navigation-bar :enable-notifications] + [page-title] + [rn/view {:style style/page-illustration} + [quo/text + "Illustration here"]] + [rn/view {:style (style/buttons insets)} + [quo/button + {:on-press #(rf/dispatch [:init-root :shell-stack]) + :type :primary + :accessibility-label :welcome-button + :override-background-color (colors/custom-color profile-color 60)} + (i18n/label :t/start-using-status)]]])) diff --git a/src/status_im2/contexts/quo_preview/animated_header_list/animated_header_list.cljs b/src/status_im2/contexts/quo_preview/animated_header_list/animated_header_list.cljs index c7464ed857..f086a9ced3 100644 --- a/src/status_im2/contexts/quo_preview/animated_header_list/animated_header_list.cljs +++ b/src/status_im2/contexts/quo_preview/animated_header_list/animated_header_list.cljs @@ -34,20 +34,16 @@ [quo/text {:size :paragraph-2} "Some random description • Developer • Designer • Olympic gold winner • President • Super Hero"]]}]) -(defn display-picture-comp +(defn f-display-picture-comp [animation] - [:f> - (fn [] - [reanimated/fast-image - {:style (reanimated/apply-animations-to-style - {:width animation - :height animation} - {:border-radius 72}) - :source - {:uri - "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg"}}])]) - - + [reanimated/fast-image + {:style (reanimated/apply-animations-to-style + {:width animation + :height animation} + {:border-radius 72}) + :source + {:uri + "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg"}}]) (defn header-comp [] @@ -78,7 +74,7 @@ {:theme-color theme-color :cover-uri "https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/kitten-playing-with-toy-mouse-royalty-free-image-590055188-1542816918.jpg?crop=1.00xw:0.758xh;0,0.132xh&resize=480:*" - :display-picture-comp display-picture-comp + :f-display-picture-comp f-display-picture-comp :header-comp header-comp :title-comp title-comp :main-comp main-comp diff --git a/src/status_im2/contexts/quo_preview/navigation/bottom_nav_tab.cljs b/src/status_im2/contexts/quo_preview/navigation/bottom_nav_tab.cljs index 0f01c447d8..36d115b6bc 100644 --- a/src/status_im2/contexts/quo_preview/navigation/bottom_nav_tab.cljs +++ b/src/status_im2/contexts/quo_preview/navigation/bottom_nav_tab.cljs @@ -45,6 +45,16 @@ pass-through? colors/white-opa-40 :else colors/neutral-50)) +(defn- f-bottom-tab + [state selected? pass-through?] + (let [icon-color-anim (reanimated/use-shared-value colors/white)] + (reanimated/set-shared-value + icon-color-anim + (get-icon-color selected? pass-through?)) + [quo2/bottom-nav-tab + (merge state {:icon-color-anim icon-color-anim}) + (:value state)])) + (defn cool-preview [] (let [state (reagent/atom {:icon :i/communities @@ -54,21 +64,14 @@ :preview-label-color colors/white}) selected? (reagent/cursor state [:selected?]) pass-through? (reagent/cursor state [:pass-through?])] - [:f> - (fn [] - (let [icon-color-anim (reanimated/use-shared-value colors/white)] - (reanimated/set-shared-value - icon-color-anim - (get-icon-color @selected? @pass-through?)) - [rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!} - [rn/view {:padding-bottom 150} - [preview/customizer state descriptor] - [rn/view - {:padding-vertical 60 - :align-items :center} - [quo2/bottom-nav-tab - (merge @state {:icon-color-anim icon-color-anim}) - (:value @state)]]]]))])) + (fn [] + [rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!} + [rn/view {:padding-bottom 150} + [preview/customizer state descriptor] + [rn/view + {:padding-vertical 60 + :align-items :center} + [:f> f-bottom-tab @state @selected? @pass-through?]]]]))) (defn preview-bottom-nav-tab [] diff --git a/src/status_im2/contexts/quo_preview/navigation/floating_shell_button.cljs b/src/status_im2/contexts/quo_preview/navigation/floating_shell_button.cljs index 81695ee46f..763a31053a 100644 --- a/src/status_im2/contexts/quo_preview/navigation/floating_shell_button.cljs +++ b/src/status_im2/contexts/quo_preview/navigation/floating_shell_button.cljs @@ -43,20 +43,23 @@ (= scroll-type :scroll-to-bottom) (assoc :scroll-to-bottom {:on-press #()}))) +(defn- f-shell-button + [state] + [quo2/floating-shell-button (mock-data state) + nil (reanimated/use-shared-value 1)]) + (defn cool-preview [] (let [state (reagent/atom {:show-jump-to? true :scroll-type :notification-down})] - [:f> - (fn [] - [rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!} - [rn/view {:padding-bottom 150} - [preview/customizer state descriptor] - [rn/view - {:padding-vertical 60 - :align-items :center} - [quo2/floating-shell-button (mock-data @state) - nil (reanimated/use-shared-value 1)]]]])])) + (fn [] + [rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!} + [rn/view {:padding-bottom 150} + [preview/customizer state descriptor] + [rn/view + {:padding-vertical 60 + :align-items :center} + [:f> f-shell-button @state]]]]))) (defn preview-floating-shell-button [] diff --git a/src/status_im2/contexts/shell/bottom_tabs.cljs b/src/status_im2/contexts/shell/bottom_tabs.cljs index bcf9f6ff4f..606b42b1f4 100644 --- a/src/status_im2/contexts/shell/bottom_tabs.cljs +++ b/src/status_im2/contexts/shell/bottom_tabs.cljs @@ -29,30 +29,32 @@ :on-press #(animation/bottom-tab-on-press stack-id) :accessibility-label (str (name stack-id) "-tab"))]) +(defn- f-bottom-tabs + [] + (let [notifications-data (rf/sub [:shell/bottom-tabs-notifications-data]) + pass-through? (rf/sub [:shell/shell-pass-through?]) + shared-values @animation/shared-values-atom + original-style (style/bottom-tabs-container pass-through?) + animated-style (reanimated/apply-animations-to-style + {:height (:bottom-tabs-height shared-values)} + original-style) + messages-double-tap-gesture (-> (gesture/gesture-tap) + (gesture/number-of-taps 2) + (gesture/on-start + (fn [_event] + (rf/dispatch [:messages-home/select-tab :tab/recent]))))] + (animation/load-stack @animation/selected-stack-id) + (reanimated/set-shared-value (:pass-through? shared-values) pass-through?) + [reanimated/view {:style animated-style} + (when pass-through? + [blur/view (blur-overlay-params style/bottom-tabs-blur-overlay)]) + [rn/view {:style (style/bottom-tabs)} + [bottom-tab :i/communities :communities-stack shared-values notifications-data] + [gesture/gesture-detector {:gesture messages-double-tap-gesture} + [bottom-tab :i/messages :chats-stack shared-values notifications-data]] + [bottom-tab :i/wallet :wallet-stack shared-values notifications-data] + [bottom-tab :i/browser :browser-stack shared-values notifications-data]]])) + (defn bottom-tabs [] - [:f> - (fn [] - (let [notifications-data (rf/sub [:shell/bottom-tabs-notifications-data]) - pass-through? (rf/sub [:shell/shell-pass-through?]) - shared-values @animation/shared-values-atom - original-style (style/bottom-tabs-container pass-through?) - animated-style (reanimated/apply-animations-to-style - {:height (:bottom-tabs-height shared-values)} - original-style) - messages-double-tap-gesture (-> (gesture/gesture-tap) - (gesture/number-of-taps 2) - (gesture/on-start - (fn [_event] - (rf/dispatch [:messages-home/select-tab :tab/recent]))))] - (animation/load-stack @animation/selected-stack-id) - (reanimated/set-shared-value (:pass-through? shared-values) pass-through?) - [reanimated/view {:style animated-style} - (when pass-through? - [blur/view (blur-overlay-params style/bottom-tabs-blur-overlay)]) - [rn/view {:style (style/bottom-tabs)} - [bottom-tab :i/communities :communities-stack shared-values notifications-data] - [gesture/gesture-detector {:gesture messages-double-tap-gesture} - [bottom-tab :i/messages :chats-stack shared-values notifications-data]] - [bottom-tab :i/wallet :wallet-stack shared-values notifications-data] - [bottom-tab :i/browser :browser-stack shared-values notifications-data]]]))]) + [:f> f-bottom-tabs]) diff --git a/src/status_im2/contexts/shell/constants.cljs b/src/status_im2/contexts/shell/constants.cljs index 28778e4dc5..0dfeab91f4 100644 --- a/src/status_im2/contexts/shell/constants.cljs +++ b/src/status_im2/contexts/shell/constants.cljs @@ -1,7 +1,7 @@ (ns status-im2.contexts.shell.constants - (:require [react-native.core :as rn] - [react-native.platform :as platform] - [utils.re-frame :as rf])) + (:require [react-native.platform :as platform] + [utils.re-frame :as rf] + [react-native.safe-area :as safe-area])) (def shell-animation-time 200) @@ -15,7 +15,7 @@ (defn status-bar-offset [] - (if platform/android? (rn/status-bar-height) 0)) + (if platform/android? (safe-area/get-top) 0)) ;; status bar height is not included in : the dimensions/window for devices with a notch ;; https://github.com/facebook/react-native/issues/23693#issuecomment-662860819 diff --git a/src/status_im2/contexts/shell/home_stack.cljs b/src/status_im2/contexts/shell/home_stack.cljs index bd18685f35..ff14d4bcd4 100644 --- a/src/status_im2/contexts/shell/home_stack.cljs +++ b/src/status_im2/contexts/shell/home_stack.cljs @@ -16,44 +16,41 @@ :browser-stack @animation/load-browser-stack? :wallet-stack @animation/load-wallet-stack?)) -(defn stack-view +(defn- f-stack-view [stack-id shared-values] - (when (load-stack? stack-id) - [:f> - (fn [] - [reanimated/view - {:style (reanimated/apply-animations-to-style - {:opacity (get shared-values - (get shell.constants/stacks-opacity-keywords stack-id)) - :pointer-events (get shared-values - (get shell.constants/stacks-pointer-keywords stack-id))} - {:position :absolute - :top 0 - :bottom 0 - :left 0 - :right 0 - :accessibility-label stack-id})} - (case stack-id - :communities-stack [communities/home] - :chats-stack [chat/home] - :wallet-stack [wallet.accounts/accounts-overview] - :browser-stack [browser.stack/browser-stack])])])) + ;; TODO lazy loading doesn't work with functional components with hoocks (when (load-stack? stack-id)) + ;; Error: Rendered more hooks than during the previous render. + [reanimated/view + {:style (reanimated/apply-animations-to-style + {:opacity (get shared-values + (get shell.constants/stacks-opacity-keywords stack-id)) + :pointer-events (get shared-values + (get shell.constants/stacks-pointer-keywords stack-id))} + {:position :absolute + :top 0 + :bottom 0 + :left 0 + :right 0 + :accessibility-label stack-id})} + (case stack-id + :communities-stack [communities/home] + :chats-stack [chat/home] + :wallet-stack [wallet.accounts/accounts-overview] + :browser-stack [browser.stack/browser-stack])]) -(defn home-stack +(defn f-home-stack [] - [:f> - (fn [] - (let [shared-values @animation/shared-values-atom - home-stack-original-style (styles/home-stack @animation/screen-height) - home-stack-animated-style (reanimated/apply-animations-to-style - {:top (:home-stack-top shared-values) - :left (:home-stack-left shared-values) - :opacity (:home-stack-opacity shared-values) - :pointer-events (:home-stack-pointer shared-values) - :transform [{:scale (:home-stack-scale shared-values)}]} - home-stack-original-style)] - [reanimated/view {:style home-stack-animated-style} - [stack-view :communities-stack shared-values] - [stack-view :chats-stack shared-values] - [stack-view :browser-stack shared-values] - [stack-view :wallet-stack shared-values]]))]) + (let [shared-values @animation/shared-values-atom + home-stack-original-style (styles/home-stack @animation/screen-height) + home-stack-animated-style (reanimated/apply-animations-to-style + {:top (:home-stack-top shared-values) + :left (:home-stack-left shared-values) + :opacity (:home-stack-opacity shared-values) + :pointer-events (:home-stack-pointer shared-values) + :transform [{:scale (:home-stack-scale shared-values)}]} + home-stack-original-style)] + [reanimated/view {:style home-stack-animated-style} + [:f> f-stack-view :communities-stack shared-values] + [:f> f-stack-view :chats-stack shared-values] + [:f> f-stack-view :browser-stack shared-values] + [:f> f-stack-view :wallet-stack shared-values]])) diff --git a/src/status_im2/contexts/shell/view.cljs b/src/status_im2/contexts/shell/view.cljs index 155888be56..b06cbae586 100644 --- a/src/status_im2/contexts/shell/view.cljs +++ b/src/status_im2/contexts/shell/view.cljs @@ -23,7 +23,7 @@ {:colors [colors/neutral-100-opa-0 colors/neutral-100-opa-100] :start {:x 0 :y 0} :end {:x 0 :y 1} - :style (style/placeholder-container (rn/status-bar-height))} + :style (style/placeholder-container (safe-area/get-top))} [rn/image {:source nil ;; TODO(parvesh) - add placeholder image :style style/placeholder-image}] @@ -44,7 +44,7 @@ [quo/text {:size :heading-1 :weight :semi-bold - :style (style/jump-to-text (rn/status-bar-height))} + :style (style/jump-to-text (safe-area/get-top))} (i18n/label :t/jump-to)]) (defn render-card @@ -96,22 +96,21 @@ [] (let [switcher-cards (rf/sub [:shell/sorted-switcher-cards]) width (rf/sub [:dimensions/window-width]) + top (safe-area/get-top) shell-margin (/ (- width 320) 3)] ;; 320 - two cards width - [safe-area/consumer - (fn [insets] - [rn/view - {:style {:top 0 - :left 0 - :right 0 - :bottom -1 - :position :absolute - :background-color colors/neutral-100}} - [jump-to-list switcher-cards shell-margin] - [top-nav-blur-overlay (:top insets)] - [common.home/top-nav - {:type :shell - :style {:margin-top (:top insets) - :z-index 2}}]])])) + [rn/view + {:style {:top 0 + :left 0 + :right 0 + :bottom -1 + :position :absolute + :background-color colors/neutral-100}} + [jump-to-list switcher-cards shell-margin] + [top-nav-blur-overlay top] + [common.home/top-nav + {:type :shell + :style {:margin-top top + :z-index 2}}]])) (defn on-layout [evt] @@ -133,21 +132,23 @@ (reset! animation/screen-height height) (async-storage/set-item! :screen-height height)))) +(defn f-shell-stack + [] + (let [shared-values (animation/calculate-shared-values)] + [rn/view + {:style {:flex 1} + :on-layout on-layout} + [shell] + [bottom-tabs/bottom-tabs] + [:f> home-stack/f-home-stack] + [quo/floating-shell-button + {:jump-to {:on-press #(animation/close-home-stack true) + :label (i18n/label :t/jump-to)}} + {:position :absolute + :bottom (+ (shell.constants/bottom-tabs-container-height) 7)} ;; bottom offset is 12 = 7 + + ;; 5(padding on button) + (:home-stack-opacity shared-values)]])) + (defn shell-stack [] - [:f> - (fn [] - (let [shared-values (animation/calculate-shared-values)] - [rn/view - {:style {:flex 1} - :on-layout on-layout} - [shell] - [bottom-tabs/bottom-tabs] - [home-stack/home-stack] - [quo/floating-shell-button - {:jump-to {:on-press #(animation/close-home-stack true) - :label (i18n/label :t/jump-to)}} - {:position :absolute - :bottom (+ (shell.constants/bottom-tabs-container-height) 7)} ;; bottom offset is 12 = 7 + - ;; 5(padding on button) - (:home-stack-opacity shared-values)]]))]) + [:f> f-shell-stack]) diff --git a/src/status_im2/contexts/syncing/setup_syncing/view.cljs b/src/status_im2/contexts/syncing/setup_syncing/view.cljs index 3e21f0e2ca..72766682b6 100644 --- a/src/status_im2/contexts/syncing/setup_syncing/view.cljs +++ b/src/status_im2/contexts/syncing/setup_syncing/view.cljs @@ -42,6 +42,10 @@ connection-string constants/local-pairing-connection-string-identifier))) +(defn f-use-interval + [clock cleanup-clock delay] + (hooks/use-interval clock cleanup-clock delay)) + (defn view [] (let [valid-for-ms (reagent/atom code-valid-for-ms) @@ -67,82 +71,78 @@ (reset! code nil) (reset! timestamp nil) (reset! valid-for-ms code-valid-for-ms))] - [:f> - (fn [] - (hooks/use-interval clock - cleanup-clock - @delay) - [safe-area/consumer - (fn [{:keys [top]}] - [rn/view {:style (style/container-main top)} - [rn/scroll-view {} - [navigation-bar] - [rn/view {:style style/page-container} - [rn/view {:style style/title-container} + + (fn [] + [:f> f-use-interval clock cleanup-clock @delay] + [rn/view {:style (style/container-main (safe-area/get-top))} + [rn/scroll-view {} + [navigation-bar] + [rn/view {:style style/page-container} + [rn/view {:style style/title-container} + [quo/text + {:size :heading-1 + :weight :semi-bold + :style {:color colors/white}} + (i18n/label :t/setup-syncing)]] + [rn/view {:style (style/qr-container (valid-cs? @code))} + (if (valid-cs? @code) + [qr-code-viewer/qr-code-view 331 @code] + [quo/qr-code + {:source (resources/get-image :qr-code) + :height 220 + :width "100%"}]) + (when-not (valid-cs? @code) + [quo/button + {:on-press (fn [] + ;TODO https://github.com/status-im/status-mobile/issues/15570 + ;remove old bottom sheet when Authentication process design is created. + (rf/dispatch [:bottom-sheet/hide-old]) + (rf/dispatch [:bottom-sheet/show-sheet-old + {:content (fn [] + [enter-password/sheet set-code])}])) + :size 40 + :style style/generate-button + :before :i/reveal} (i18n/label :t/reveal-sync-code)]) + (when (valid-cs? @code) + [rn/view + {:style style/valid-cs-container} + [rn/view + {:style style/sub-text-container} [quo/text - {:size :heading-1 - :weight :semi-bold - :style {:color colors/white}} - (i18n/label :t/setup-syncing)]] - [rn/view {:style (style/qr-container (valid-cs? @code))} - (if (valid-cs? @code) - [qr-code-viewer/qr-code-view 331 @code] - [quo/qr-code - {:source (resources/get-image :qr-code) - :height 220 - :width "100%"}]) - (when-not (valid-cs? @code) - [quo/button - {:on-press (fn [] - ;TODO https://github.com/status-im/status-mobile/issues/15570 - ;remove old bottom sheet when Authentication process design is created. - (rf/dispatch [:bottom-sheet/hide-old]) - (rf/dispatch [:bottom-sheet/show-sheet-old - {:content (fn [] - [enter-password/sheet set-code])}])) - :size 40 - :style style/generate-button - :before :i/reveal} (i18n/label :t/reveal-sync-code)]) - (when (valid-cs? @code) - [rn/view - {:style style/valid-cs-container} - [rn/view - {:style style/sub-text-container} - [quo/text - {:size :paragraph-2 - :style {:color colors/white-opa-40}} - (i18n/label :t/sync-code)] - [quo/text - {:size :paragraph-2 - :style {:color (if (< @valid-for-ms one-min-ms) - colors/danger-60 - colors/white-opa-40)}} - (i18n/label :t/valid-for-time {:valid-for (datetime/ms-to-duration @valid-for-ms)})]] - [quo/input - {:default-value @code - :type :password - :override-theme :dark - :default-shown? true - :editable false}] - [quo/button - {:on-press (fn [] - (clipboard/set-string @code) - (rf/dispatch [:toasts/upsert - {:icon :correct - :icon-color colors/success-50 - :text (i18n/label - :t/sharing-copied-to-clipboard)}])) - :override-theme :dark - :type :grey - :style {:margin-top 12} - :before :i/copy} - (i18n/label :t/copy-qr)]])]] - [rn/view {:style style/sync-code} - [quo/divider-label - {:label (i18n/label :t/have-a-sync-code?) - :increase-padding-top? true}] - [quo/action-drawer - [[{:icon :i/scan - :override-theme :dark - :on-press #(js/alert "to be implemented") - :label (i18n/label :t/Scan-or-enter-sync-code)}]]]]]])])])) + {:size :paragraph-2 + :style {:color colors/white-opa-40}} + (i18n/label :t/sync-code)] + [quo/text + {:size :paragraph-2 + :style {:color (if (< @valid-for-ms one-min-ms) + colors/danger-60 + colors/white-opa-40)}} + (i18n/label :t/valid-for-time {:valid-for (datetime/ms-to-duration @valid-for-ms)})]] + [quo/input + {:default-value @code + :type :password + :override-theme :dark + :default-shown? true + :editable false}] + [quo/button + {:on-press (fn [] + (clipboard/set-string @code) + (rf/dispatch [:toasts/upsert + {:icon :correct + :icon-color colors/success-50 + :text (i18n/label + :t/sharing-copied-to-clipboard)}])) + :override-theme :dark + :type :grey + :style {:margin-top 12} + :before :i/copy} + (i18n/label :t/copy-qr)]])]] + [rn/view {:style style/sync-code} + [quo/divider-label + {:label (i18n/label :t/have-a-sync-code?) + :increase-padding-top? true}] + [quo/action-drawer + [[{:icon :i/scan + :override-theme :dark + :on-press #(js/alert "to be implemented") + :label (i18n/label :t/Scan-or-enter-sync-code)}]]]]]]))) diff --git a/src/status_im2/navigation/view.cljs b/src/status_im2/navigation/view.cljs index 6e15da727b..6e17d94635 100644 --- a/src/status_im2/navigation/view.cljs +++ b/src/status_im2/navigation/view.cljs @@ -40,55 +40,52 @@ :z-index 999999999999999999}])) (defn wrapped-screen-style - [{:keys [top? bottom?]} insets background-color] + [{:keys [top? bottom?]} background-color] (merge {:flex 1 :background-color (or background-color (colors/theme-colors colors/white colors/neutral-100))} (when bottom? - {:padding-bottom (:bottom insets)}) + {:padding-bottom (safe-area/get-bottom)}) (when top? - {:padding-top (:top insets)}))) + {:padding-top (safe-area/get-top)}))) (defn screen [key] - (reagent.core/reactify-component - (fn [] - (let [{:keys [component options]} - (get (if js/goog.DEBUG (get-screens) screens) (keyword key)) ;; needed for hot reload - {:keys [insets sheet?]} options - background-color (or (get-in options [:layout :backgroundColor]) - (when sheet? :transparent))] + (let [{:keys [component options]} + (get (if js/goog.DEBUG (get-screens) screens) (keyword key)) ;; needed for hot reload + {:keys [insets sheet?]} options + background-color (or (get-in options [:layout :backgroundColor]) + (when sheet? :transparent))] + (reagent.core/reactify-component + (fn [] ^{:key (str "root" key @reloader/cnt)} - [safe-area/provider - [safe-area/consumer - (fn [safe-insets] - [rn/view - {:style (wrapped-screen-style insets safe-insets background-color)} - [inactive] - (if sheet? - [bottom-sheet-screen/view component] - [component])])] + [:<> + [rn/view + {:style (wrapped-screen-style insets background-color)} + [inactive] + (if sheet? + [:f> bottom-sheet-screen/f-view component] + [component])] (when js/goog.DEBUG [reloader/reload-view])])))) (def bottom-sheet (reagent/reactify-component (fn [] - ^{:key (str "sheet" @reloader/cnt)} - [safe-area/provider - [inactive] - [safe-area/consumer - (fn [insets] - (let [{:keys [sheets hide?]} (rf/sub [:bottom-sheet]) - sheet (last sheets)] - [rn/keyboard-avoiding-view - {:style {:position :relative :flex 1} - :keyboard-vertical-offset (- (max 20 (:bottom insets)))} - (when sheet - [:f> - bottom-sheet/view - {:insets insets :hide? hide?} - sheet])]))]]))) + (let [{:keys [sheets hide?]} (rf/sub [:bottom-sheet]) + sheet (last sheets) + insets (safe-area/get-insets)] + ^{:key (str "sheet" @reloader/cnt)} + [:<> + [inactive] + [rn/keyboard-avoiding-view + {:style {:position :relative :flex 1} + :keyboard-vertical-offset (- (max 20 (:bottom insets)))} + (when sheet + [:f> + bottom-sheet/view + {:insets insets :hide? hide?} + sheet])]])))) (def toasts (reagent/reactify-component toasts/toasts)) @@ -97,7 +94,7 @@ (reagent/reactify-component (fn [] ^{:key (str "popover" @reloader/cnt)} - [safe-area/provider + [:<> [inactive] [popover/popover] (when js/goog.DEBUG @@ -107,7 +104,7 @@ (reagent/reactify-component (fn [] ^{:key (str "visibility-status-popover" @reloader/cnt)} - [safe-area/provider + [rn/view [inactive] [visibility-status-views/visibility-status-popover] (when js/goog.DEBUG @@ -117,7 +114,7 @@ (reagent/reactify-component (fn [] ^{:key (str "sheet-old" @reloader/cnt)} - [safe-area/provider + [:<> [inactive] [bottom-sheets-old/bottom-sheet]]))) @@ -125,7 +122,7 @@ (reagent/reactify-component (fn [] ^{:key (str "signing-sheet" @reloader/cnt)} - [safe-area/provider + [:<> [inactive] [signing/signing] (when js/goog.DEBUG @@ -135,7 +132,7 @@ (reagent/reactify-component (fn [] ^{:key (str "select-acc-sheet" @reloader/cnt)} - [safe-area/provider + [:<> [inactive] [wallet.send.views/select-account] (when js/goog.DEBUG @@ -145,7 +142,7 @@ (reagent/reactify-component (fn [] ^{:key (str "wallet-connect-sheet" @reloader/cnt)} - [safe-area/provider + [:<> [inactive] [wallet-connect/wallet-connect-proposal-sheet] (when js/goog.DEBUG @@ -155,7 +152,7 @@ (reagent/reactify-component (fn [] ^{:key (str "wallet-connect-success-sheet" @reloader/cnt)} - [safe-area/provider + [:<> [inactive] [wallet-connect/wallet-connect-success-sheet-view] (when js/goog.DEBUG @@ -165,7 +162,7 @@ (reagent/reactify-component (fn [] ^{:key (str "wallet-connect-app-management-sheet" @reloader/cnt)} - [safe-area/provider + [:<> [inactive] [wallet-connect/wallet-connect-app-management-sheet-view] (when js/goog.DEBUG diff --git a/test/jest/jest.config.js b/test/jest/jest.config.js index 4f71d61960..4aeaff7631 100644 --- a/test/jest/jest.config.js +++ b/test/jest/jest.config.js @@ -12,7 +12,7 @@ module.exports = { }, testTimeout: 60000, transformIgnorePatterns: [ - '/node_modules/(?!(@react-native|react-native-haptic-feedback|react-native-redash|react-native-image-crop-picker|@react-native-community|react-native-linear-gradient|react-native-background-timer|react-native|rn-emoji-keyboard|react-native-languages|react-native-shake|react-native-reanimated|react-native-redash|react-native-permissions|@react-native-community/blur)/).*/', + '/node_modules/(?!(@react-native|react-native-haptic-feedback|react-native-redash|react-native-image-crop-picker|@react-native-community|react-native-linear-gradient|react-native-background-timer|react-native|rn-emoji-keyboard|react-native-languages|react-native-shake|react-native-reanimated|react-native-redash|react-native-permissions|@react-native-community/blur|react-native-static-safe-area-insets)/).*/', ], globals: { __TEST__: true, diff --git a/yarn.lock b/yarn.lock index eebb0fd155..12c1a7ed61 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8835,11 +8835,6 @@ react-native-redash@^16.0.11: normalize-svg-path "^1.0.1" parse-svg-path "^0.1.2" -react-native-safe-area-context@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-2.0.0.tgz#7ef48e5a83a1e2f7fe9d5321493822b6765fd1ab" - integrity sha512-5VtCI3Nluzm7QfTcB/3j4YeWqt25QO1u5KTA1jEg1ckJzV19qCZFyHIpCCkS5+VEX+2JEHfdczhCdwE5sPgyEw== - react-native-safe-modules@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/react-native-safe-modules/-/react-native-safe-modules-1.0.3.tgz#f5f29bb9d09d17581193843d4173ad3054f74890" @@ -8867,6 +8862,11 @@ react-native-share@^7.0.1: resolved "https://registry.yarnpkg.com/react-native-share/-/react-native-share-7.0.1.tgz#1deef27afcd8275222ba0efeac337e7cea99bc4b" integrity sha512-hq7nOirgih/zIF9UU9FuYKZ3NGvasu2c/eJesvyPKYiykTtgQZM+mvDwFk/ogEsGwRtTPJBtj8/6IyIFcGa7lw== +react-native-static-safe-area-insets@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/react-native-static-safe-area-insets/-/react-native-static-safe-area-insets-2.2.0.tgz#dd86b6a38f43964fac8df8c0e6bc8e062527786c" + integrity sha512-TLTW2e2kRK3COSK8gMZzwp4wHguFCtcO18itDLn5av/xQblXt9ylu84o+qD9aKJCBfvtNzGOvqqTKqC5GJRZ/g== + "react-native-status-keycard@git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39": version "2.5.39" resolved "git+https://github.com/status-im/react-native-status-keycard.git#93dd64754e676172310e6ea7187cc49f2dc013c6"