updates
This commit is contained in:
+11
-3
@@ -234,7 +234,7 @@ PODS:
|
||||
- React
|
||||
- react-native-blob-util (0.13.18):
|
||||
- React-Core
|
||||
- react-native-blur (4.3.0):
|
||||
- react-native-blur (4.3.2):
|
||||
- React-Core
|
||||
- react-native-camera-kit (8.0.4):
|
||||
- React
|
||||
@@ -695,6 +695,7 @@ SPEC CHECKSUMS:
|
||||
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
glog: 36ce0530c6d2c3a5a4326885ef4069564887a1db
|
||||
>>>>>>> 1ae28d67c (updates)
|
||||
@@ -707,6 +708,9 @@ SPEC CHECKSUMS:
|
||||
=======
|
||||
glog: 6934faae5afbec23475648c8aeb6047ce973af65
|
||||
>>>>>>> d31ec1795 (updates)
|
||||
=======
|
||||
glog: 36ce0530c6d2c3a5a4326885ef4069564887a1db
|
||||
>>>>>>> 12ff0b995 (updates)
|
||||
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
||||
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
|
||||
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
|
||||
@@ -726,7 +730,7 @@ SPEC CHECKSUMS:
|
||||
React-logger: 85f4ef06b9723714b2dfa5b0e5502b673b271b58
|
||||
react-native-background-timer: 1f7d560647b40e6a60b01c452ba29c54bf581fc4
|
||||
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
|
||||
react-native-blur: 50c9feabacbc5f49b61337ebc32192c6be7ec3c3
|
||||
react-native-blur: 4db8c7556566df4e8714c1af5762a4ebc99175d5
|
||||
react-native-camera-kit: 498a6d111a904834e0824e9073cfadef7303235f
|
||||
react-native-cameraroll: 88f4e62d9ecd0e1f253abe4f685474f2ea14bfa2
|
||||
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
|
||||
@@ -785,6 +789,7 @@ SPEC CHECKSUMS:
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
PODFILE CHECKSUM: c29de3b14e3275299c51aa95520622f09d084bcb
|
||||
=======
|
||||
PODFILE CHECKSUM: a8a81808e948d1103fdd28ef7fe16d5f045fef62
|
||||
@@ -798,5 +803,8 @@ PODFILE CHECKSUM: a8a81808e948d1103fdd28ef7fe16d5f045fef62
|
||||
=======
|
||||
PODFILE CHECKSUM: dd4d6510a5580d20adac6c8a8dad97a0bc7d6508
|
||||
>>>>>>> d31ec1795 (updates)
|
||||
=======
|
||||
PODFILE CHECKSUM: a8a81808e948d1103fdd28ef7fe16d5f045fef62
|
||||
>>>>>>> 12ff0b995 (updates)
|
||||
|
||||
COCOAPODS: 1.12.0
|
||||
COCOAPODS: 1.11.3
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
(ns status-im2.contexts.chat.messages.bottom-sheet-composer.actions.style
|
||||
(:require [status-im2.contexts.chat.messages.bottom-sheet-composer.constants :as c]))
|
||||
|
||||
|
||||
(defn actions-container
|
||||
[]
|
||||
{:height c/actions-container-height
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:z-index 2
|
||||
:flex-direction :row})
|
||||
@@ -0,0 +1,133 @@
|
||||
(ns status-im2.contexts.chat.messages.bottom-sheet-composer.actions.view
|
||||
(:require
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.background-timer :as background-timer]
|
||||
[react-native.core :as rn]
|
||||
[react-native.permissions :as permissions]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.alert.events :as alert]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.constants :as c]
|
||||
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.actions.style :as style]))
|
||||
|
||||
|
||||
;;; CONTROLS
|
||||
(defn send-button
|
||||
[input-ref text-value images? window-height
|
||||
{:keys [height saved-height last-height opacity background-y container-opacity]}]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [btn-opacity (reanimated/use-shared-value 0)
|
||||
z-index (reagent/atom 0)]
|
||||
[:f>
|
||||
(fn []
|
||||
(rn/use-effect (fn []
|
||||
(if (or (not-empty @text-value) images?)
|
||||
(when-not (= @z-index 1)
|
||||
(reset! z-index 1)
|
||||
(js/setTimeout #(reanimated/animate btn-opacity 1) 50))
|
||||
(when-not (= @z-index 0)
|
||||
(reanimated/animate btn-opacity 0)
|
||||
(js/setTimeout #(reset! z-index 0) 300))))
|
||||
[@text-value])
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity btn-opacity}
|
||||
{:position :absolute
|
||||
:right 0
|
||||
:z-index @z-index
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95)})}
|
||||
[quo/button
|
||||
{:icon true
|
||||
:size 32
|
||||
:accessibility-label :send-message-button
|
||||
:on-press (fn []
|
||||
(reanimated/animate height c/input-height)
|
||||
(reanimated/set-shared-value saved-height c/input-height)
|
||||
(reanimated/set-shared-value last-height c/input-height)
|
||||
(reanimated/animate opacity 0)
|
||||
(js/setTimeout #(reanimated/animate container-opacity 0.7) 300)
|
||||
(js/setTimeout #(reanimated/set-shared-value background-y
|
||||
(- window-height))
|
||||
300)
|
||||
(rf/dispatch [:chat.ui/send-current-message])
|
||||
(rf/dispatch [:chat.ui/set-input-maximized false])
|
||||
(rf/dispatch [:chat.ui/set-input-content-height c/input-height])
|
||||
(reset! text-value "")
|
||||
(.clear ^js @input-ref)
|
||||
(messages.list/scroll-to-bottom))}
|
||||
:i/arrow-up]])]))])
|
||||
|
||||
(defn audio-button
|
||||
[]
|
||||
[quo/button
|
||||
{:on-press #(js/alert "to be added")
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32}
|
||||
:i/audio])
|
||||
(defn camera-button
|
||||
[]
|
||||
[quo/button
|
||||
{:on-press #(js/alert "to be implemented")
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}}
|
||||
:i/camera])
|
||||
(defn image-button
|
||||
[insets height]
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
(permissions/request-permissions
|
||||
{:permissions [:read-external-storage :write-external-storage]
|
||||
:on-allowed (fn []
|
||||
(rf/dispatch [:chat.ui/set-input-content-height
|
||||
(reanimated/get-shared-value height)])
|
||||
(rf/dispatch [:open-modal :photo-selector {:insets insets}]))
|
||||
:on-denied (fn []
|
||||
(background-timer/set-timeout
|
||||
#(alert/show-popup (i18n/label :t/error)
|
||||
(i18n/label
|
||||
:t/external-storage-denied))
|
||||
50))}))
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}}
|
||||
:i/image])
|
||||
|
||||
(defn reaction-button
|
||||
[]
|
||||
[quo/button
|
||||
{:on-press #(js/alert "to be implemented")
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}}
|
||||
:i/reaction])
|
||||
|
||||
(defn format-button
|
||||
[]
|
||||
[quo/button
|
||||
{:on-press #(js/alert "to be implemented")
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32}
|
||||
:i/format])
|
||||
|
||||
(defn view
|
||||
[input-ref text-value images? {:keys [height] :as animations}
|
||||
window-height insets]
|
||||
[rn/view {:style (style/actions-container)}
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[camera-button]
|
||||
[image-button insets height]
|
||||
[reaction-button]
|
||||
[format-button]]
|
||||
[send-button input-ref text-value images? window-height animations]
|
||||
[audio-button]])
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
(def ^:const handle-container-height 20)
|
||||
|
||||
(def ^:const input-height (if platform/ios? 32 32))
|
||||
(def ^:const input-height (if platform/ios? 32 42))
|
||||
|
||||
(def ^:const actions-container-height 56)
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
(ns status-im2.contexts.chat.messages.bottom-sheet-composer.keyboard
|
||||
(:require [oops.core :as oops]
|
||||
[react-native.async-storage :as async-storage]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.utils :as utils]))
|
||||
|
||||
(defn get-kb-height
|
||||
[curr-height default-height]
|
||||
(if (and default-height (< curr-height default-height))
|
||||
default-height
|
||||
curr-height))
|
||||
|
||||
(defn store-kb-height
|
||||
[{:keys [kb-default-height]} keyboard-height]
|
||||
(when (and (not @kb-default-height) (pos? keyboard-height))
|
||||
(async-storage/set-item :kb-default-height keyboard-height)))
|
||||
|
||||
(defn handle-emoji-kb-ios
|
||||
[e
|
||||
{:keys [emoji-kb-extra-height]}
|
||||
{:keys [text-value]}
|
||||
{:keys [height saved-height]}
|
||||
{:keys [max-height]}]
|
||||
(let [start-h (oops/oget e "startCoordinates.height")
|
||||
end-h (oops/oget e "endCoordinates.height")
|
||||
diff (- end-h start-h)
|
||||
max (- max-height diff)
|
||||
curr-text @text-value]
|
||||
(if (> (reanimated/get-shared-value height) max)
|
||||
(do
|
||||
(reanimated/set-shared-value height (- (reanimated/get-shared-value height) diff))
|
||||
(reanimated/set-shared-value saved-height (- (reanimated/get-shared-value saved-height) diff))
|
||||
(reset! text-value (str @text-value " "))
|
||||
(js/setTimeout #(reset! text-value curr-text) 0)
|
||||
(reset! emoji-kb-extra-height diff))
|
||||
(when @emoji-kb-extra-height
|
||||
(reanimated/set-shared-value height
|
||||
(+ (reanimated/get-shared-value height) @emoji-kb-extra-height))
|
||||
(reanimated/set-shared-value saved-height
|
||||
(+ (reanimated/get-shared-value saved-height)
|
||||
@emoji-kb-extra-height))
|
||||
(reset! emoji-kb-extra-height nil)))))
|
||||
|
||||
(defn handle-kb-hide-android
|
||||
[{:keys [input-ref]}
|
||||
{:keys [opacity height saved-height background-y]}
|
||||
{:keys [window-height lines]}]
|
||||
(when platform/android?
|
||||
(let [min-height (utils/get-min-height lines)]
|
||||
(.blur ^js @input-ref)
|
||||
(reanimated/animate opacity 0)
|
||||
(js/setTimeout (fn []
|
||||
(reanimated/animate height min-height)
|
||||
(reanimated/set-shared-value saved-height min-height)
|
||||
(reanimated/set-shared-value background-y (- window-height)))
|
||||
100))))
|
||||
|
||||
(defn add-kb-listeners
|
||||
[{:keys [keyboard-show-listener keyboard-frame-listener keyboard-hide-listener] :as props}
|
||||
state animations dimensions keyboard-height]
|
||||
(reset! keyboard-show-listener (.addListener rn/keyboard
|
||||
"keyboardDidShow"
|
||||
#(store-kb-height state keyboard-height)))
|
||||
(reset! keyboard-frame-listener (.addListener
|
||||
rn/keyboard
|
||||
"keyboardWillChangeFrame"
|
||||
#(handle-emoji-kb-ios % props state animations dimensions)))
|
||||
(reset! keyboard-hide-listener (.addListener rn/keyboard
|
||||
"keyboardDidHide"
|
||||
#(handle-kb-hide-android props animations dimensions))))
|
||||
@@ -70,14 +70,6 @@
|
||||
:overflow :hidden}))
|
||||
|
||||
|
||||
(defn actions-container
|
||||
[]
|
||||
{:height c/actions-container-height
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:z-index 2
|
||||
:flex-direction :row})
|
||||
|
||||
(defn background
|
||||
[opacity background-y window-height]
|
||||
(reanimated/apply-animations-to-style
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
(ns status-im2.contexts.chat.messages.bottom-sheet-composer.sub-view
|
||||
(:require
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[react-native.linear-gradient :as linear-gradient]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.style :as style]))
|
||||
|
||||
(defn bar
|
||||
[]
|
||||
[rn/view {:style (style/bar-container)}
|
||||
[rn/view {:style (style/bar)}]])
|
||||
|
||||
(defn blur-view
|
||||
[layout-height]
|
||||
[:f>
|
||||
(fn []
|
||||
[reanimated/view {:style (style/blur-container layout-height)}
|
||||
[blur/view style/blur-view]])])
|
||||
|
||||
(defn gradients
|
||||
[{:keys [input-ref]}
|
||||
{:keys [gradient-z-index text-value focused?]}
|
||||
{:keys [gradient-opacity]}
|
||||
{:keys [lines]}]
|
||||
[:f>
|
||||
(fn []
|
||||
[:<>
|
||||
[reanimated/linear-gradient (style/top-gradient gradient-opacity @gradient-z-index)]
|
||||
(when (and (not-empty @text-value) (not @focused?) (> lines 2))
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press #(.focus ^js @input-ref)}
|
||||
[linear-gradient/linear-gradient (style/bottom-gradient)]])])])
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
(ns status-im2.contexts.chat.messages.bottom-sheet-composer.test)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
(ns status-im2.contexts.chat.messages.bottom-sheet-composer.utils
|
||||
(:require
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.constants :as c]))
|
||||
|
||||
(defn bounded-val
|
||||
[f min max]
|
||||
(Math/max min (Math/min f max)))
|
||||
|
||||
(defn get-min-height
|
||||
[lines]
|
||||
(if (> lines 1) c/multiline-minimized-height c/input-height))
|
||||
|
||||
(defn calc-reopen-height
|
||||
[text-value min-height content-height saved-height]
|
||||
(if (empty? @text-value)
|
||||
min-height
|
||||
(Math/min @content-height (reanimated/get-shared-value saved-height))))
|
||||
|
||||
(defn should-update-height
|
||||
[content-size height max-height]
|
||||
(let [diff (Math/abs (- content-size (reanimated/get-shared-value height)))]
|
||||
(and (not= (reanimated/get-shared-value height) max-height)
|
||||
(> diff c/content-change-threshold))))
|
||||
|
||||
(defn should-show-top-gradient
|
||||
[y lines max-lines gradient-opacity focused?]
|
||||
(and
|
||||
(> y c/line-height)
|
||||
(>= lines max-lines)
|
||||
(= (reanimated/get-shared-value gradient-opacity) 0)
|
||||
@focused?))
|
||||
|
||||
(defn should-hide-top-gradient
|
||||
[y gradient-opacity]
|
||||
(and
|
||||
(<= y c/line-height)
|
||||
(= (reanimated/get-shared-value gradient-opacity) 1)))
|
||||
|
||||
(defn calc-lines
|
||||
[height]
|
||||
(let [lines (Math/round (/ height c/line-height))]
|
||||
(if platform/ios? lines (dec lines))))
|
||||
|
||||
(defn calc-max-height
|
||||
[window-height margin-top kb-height images]
|
||||
(let [max-height
|
||||
(- window-height margin-top kb-height c/handle-container-height c/actions-container-height)]
|
||||
(if (seq images)
|
||||
(- max-height c/images-container-height)
|
||||
max-height)))
|
||||
|
||||
(defn empty-input?
|
||||
[input-text images]
|
||||
(and (nil? input-text) (not (seq images))))
|
||||
@@ -1,157 +1,24 @@
|
||||
(ns status-im2.contexts.chat.messages.bottom-sheet-composer.view
|
||||
(:require
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.background-timer :as background-timer]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.hooks :as hooks]
|
||||
[react-native.linear-gradient :as linear-gradient]
|
||||
[react-native.permissions :as permissions]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[oops.core :as oops]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.alert.events :as alert]
|
||||
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.style :as style]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.images.view :as images]
|
||||
[react-native.async-storage :as async-storage]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.constants :as c]))
|
||||
|
||||
;;; CONTROLS
|
||||
(defn send-button
|
||||
[input-ref text-value images? window-height
|
||||
{:keys [height saved-height last-height opacity background-y container-opacity]}]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [btn-opacity (reanimated/use-shared-value 0)
|
||||
z-index (reagent/atom 0)]
|
||||
|
||||
[:f>
|
||||
(fn []
|
||||
(rn/use-effect (fn []
|
||||
(if (or (not-empty @text-value) images?)
|
||||
(when-not (= @z-index 1)
|
||||
(reset! z-index 1)
|
||||
(js/setTimeout #(reanimated/animate btn-opacity 1) 50))
|
||||
(when-not (= @z-index 0)
|
||||
(reanimated/animate btn-opacity 0)
|
||||
(js/setTimeout #(reset! z-index 0) 300))))
|
||||
[@text-value])
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity btn-opacity}
|
||||
{:position :absolute
|
||||
:right 0
|
||||
:z-index @z-index
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-90)})}
|
||||
[quo/button
|
||||
{:icon true
|
||||
:size 32
|
||||
:accessibility-label :send-message-button
|
||||
:on-press (fn []
|
||||
(reanimated/animate height c/input-height)
|
||||
(reanimated/set-shared-value saved-height c/input-height)
|
||||
(reanimated/set-shared-value last-height c/input-height)
|
||||
(reanimated/animate opacity 0)
|
||||
(js/setTimeout #(reanimated/animate container-opacity 0.7) 300)
|
||||
(js/setTimeout #(reanimated/set-shared-value background-y
|
||||
(- window-height))
|
||||
300)
|
||||
(rf/dispatch [:chat.ui/send-current-message])
|
||||
(rf/dispatch [:chat.ui/set-input-maximized false])
|
||||
(reset! text-value "")
|
||||
(.clear ^js @input-ref)
|
||||
(messages.list/scroll-to-bottom))}
|
||||
:i/arrow-up]])]))])
|
||||
|
||||
(defn audio-button
|
||||
[]
|
||||
[quo/button
|
||||
{:on-press #(js/alert "to be added")
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32}
|
||||
:i/audio])
|
||||
(defn camera-button
|
||||
[]
|
||||
[quo/button
|
||||
{:on-press #(js/alert "to be implemented")
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}}
|
||||
:i/camera])
|
||||
(defn image-button
|
||||
[insets height]
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
(permissions/request-permissions
|
||||
{:permissions [:read-external-storage :write-external-storage]
|
||||
:on-allowed (fn []
|
||||
(rf/dispatch [:chat.ui/set-input-content-height
|
||||
(reanimated/get-shared-value height)])
|
||||
(rf/dispatch [:open-modal :photo-selector {:insets insets}]))
|
||||
:on-denied (fn []
|
||||
(background-timer/set-timeout
|
||||
#(alert/show-popup (i18n/label :t/error)
|
||||
(i18n/label
|
||||
:t/external-storage-denied))
|
||||
50))}))
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}}
|
||||
:i/image])
|
||||
|
||||
(defn reaction-button
|
||||
[]
|
||||
[quo/button
|
||||
{:on-press #(js/alert "to be implemented")
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}}
|
||||
:i/reaction])
|
||||
|
||||
(defn format-button
|
||||
[]
|
||||
[quo/button
|
||||
{:on-press #(js/alert "to be implemented")
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32}
|
||||
:i/format])
|
||||
|
||||
(defn actions
|
||||
[input-ref text-value images? {:keys [height saved-height opacity background-y] :as animations}
|
||||
window-height insets]
|
||||
[rn/view {:style (style/actions-container)}
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[camera-button]
|
||||
[image-button insets height]
|
||||
[reaction-button]
|
||||
[format-button]]
|
||||
[send-button input-ref text-value images? window-height animations]
|
||||
[audio-button]])
|
||||
|
||||
(defn bar
|
||||
[]
|
||||
[rn/view {:style (style/bar-container)}
|
||||
[rn/view {:style (style/bar)}]])
|
||||
|
||||
(defn get-min-height
|
||||
[lines]
|
||||
(if (> lines 1) c/multiline-minimized-height c/input-height))
|
||||
|
||||
(defn bounded-val
|
||||
[f min max]
|
||||
(Math/max min (Math/min f max)))
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.utils :as utils]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.constants :as c]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.actions.view :as actions]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.keyboard :as kb]
|
||||
[status-im2.contexts.chat.messages.bottom-sheet-composer.sub-view :as sub-view]))
|
||||
|
||||
(defn set-opacity
|
||||
[e opacity translation expanding? min-height max-height new-height saved-height]
|
||||
@@ -200,7 +67,7 @@
|
||||
(defn drag-gesture
|
||||
[{:keys [input-ref] :as props}
|
||||
{:keys [gesture-enabled?] :as state}
|
||||
{:keys [height saved-height last-height opacity background-y] :as animations}
|
||||
{:keys [height saved-height last-height opacity background-y container-opacity] :as animations}
|
||||
{:keys [max-height lines] :as dimensions}
|
||||
keyboard-shown]
|
||||
(let [expanding? (atom true)
|
||||
@@ -212,6 +79,7 @@
|
||||
(if-not keyboard-shown
|
||||
(do ; focus and end
|
||||
(when (< (oops/oget e "velocityY") c/velocity-threshold)
|
||||
(reanimated/animate container-opacity 1)
|
||||
(reanimated/set-shared-value last-height max-height))
|
||||
(.focus ^js @input-ref)
|
||||
(reset! gesture-enabled? false))
|
||||
@@ -220,10 +88,10 @@
|
||||
(reset! expanding? (neg? (oops/oget e "velocityY")))))))
|
||||
(gesture/on-update (fn [e]
|
||||
(let [translation (oops/oget e "translationY")
|
||||
min-height (get-min-height lines)
|
||||
min-height (utils/get-min-height lines)
|
||||
new-height (+ (- translation)
|
||||
(reanimated/get-shared-value saved-height))
|
||||
new-height (bounded-val new-height min-height max-height)]
|
||||
new-height (utils/bounded-val new-height min-height max-height)]
|
||||
(when keyboard-shown
|
||||
(reanimated/set-shared-value height new-height)
|
||||
(set-opacity e
|
||||
@@ -284,11 +152,6 @@
|
||||
(clj->js {:selection {:start @saved-cursor-position :end @saved-cursor-position}})))
|
||||
(handle-refocus-emoji-kb-ios props animations dimensions))
|
||||
|
||||
(defn calc-reopen-height
|
||||
[text-value min-height content-height saved-height]
|
||||
(if (empty? @text-value)
|
||||
min-height
|
||||
(Math/min @content-height (reanimated/get-shared-value saved-height))))
|
||||
|
||||
(defn handle-blur
|
||||
[{:keys [text-value focused? lock-selection? cursor-position saved-cursor-position gradient-z-index
|
||||
@@ -296,8 +159,8 @@
|
||||
{:keys [height saved-height last-height gradient-opacity container-opacity opacity background-y]}
|
||||
{:keys [lines content-height max-height window-height]}
|
||||
images]
|
||||
(let [min-height (get-min-height lines)
|
||||
reopen-height (calc-reopen-height text-value min-height content-height saved-height)]
|
||||
(let [min-height (utils/get-min-height lines)
|
||||
reopen-height (utils/calc-reopen-height text-value min-height content-height saved-height)]
|
||||
(reset! focused? false)
|
||||
(reanimated/set-shared-value last-height reopen-height)
|
||||
(reanimated/animate height min-height)
|
||||
@@ -313,12 +176,6 @@
|
||||
(when (not= reopen-height max-height)
|
||||
(reset! maximized? false))))
|
||||
|
||||
(defn should-update-height
|
||||
[content-size height max-height]
|
||||
(let [diff (Math/abs (- content-size (reanimated/get-shared-value height)))]
|
||||
(and (not= (reanimated/get-shared-value height) max-height)
|
||||
(> diff c/content-change-threshold))))
|
||||
|
||||
(defn handle-content-size-change
|
||||
[e
|
||||
{:keys [maximized?]}
|
||||
@@ -327,9 +184,9 @@
|
||||
keyboard-shown]
|
||||
(when keyboard-shown
|
||||
(let [content-size (+ (oops/oget e "nativeEvent.contentSize.height") c/extra-content-offset)
|
||||
new-height (bounded-val content-size c/input-height max-height)]
|
||||
new-height (utils/bounded-val content-size c/input-height max-height)]
|
||||
(reset! content-height content-size)
|
||||
(when (should-update-height content-size height max-height)
|
||||
(when (utils/should-update-height content-size height max-height)
|
||||
(reanimated/animate height new-height)
|
||||
(reanimated/set-shared-value saved-height new-height))
|
||||
(when (= new-height max-height)
|
||||
@@ -344,30 +201,16 @@
|
||||
(js/setTimeout #(reanimated/set-shared-value background-y (- window-height)) 300)))
|
||||
(rf/dispatch [:chat.ui/set-input-content-height new-height]))))
|
||||
|
||||
(defn should-show-top-gradient
|
||||
[y lines max-lines gradient-opacity focused?]
|
||||
(and
|
||||
(> y c/line-height)
|
||||
(>= lines max-lines)
|
||||
(= (reanimated/get-shared-value gradient-opacity) 0)
|
||||
@focused?))
|
||||
|
||||
(defn should-hide-top-gradient
|
||||
[y gradient-opacity]
|
||||
(and
|
||||
(<= y c/line-height)
|
||||
(= (reanimated/get-shared-value gradient-opacity) 1)))
|
||||
|
||||
(defn handle-scroll
|
||||
[e
|
||||
{:keys [gradient-z-index focused?]}
|
||||
{:keys [gradient-opacity]}
|
||||
{:keys [lines max-lines]}]
|
||||
(let [y (oops/oget e "nativeEvent.contentOffset.y")]
|
||||
(when (should-show-top-gradient y lines max-lines gradient-opacity focused?)
|
||||
(when (utils/should-show-top-gradient y lines max-lines gradient-opacity focused?)
|
||||
(reset! gradient-z-index 1)
|
||||
(js/setTimeout #(reanimated/animate gradient-opacity 1) 0))
|
||||
(when (should-hide-top-gradient y gradient-opacity)
|
||||
(when (utils/should-hide-top-gradient y gradient-opacity)
|
||||
(reanimated/animate gradient-opacity 0)
|
||||
(js/setTimeout #(reset! gradient-z-index 0) 300))))
|
||||
|
||||
@@ -387,46 +230,6 @@
|
||||
(when-not @lock-selection?
|
||||
(reset! cursor-position (oops/oget e "nativeEvent.selection.end"))))
|
||||
|
||||
(defn handle-emoji-kb-ios
|
||||
[e
|
||||
{:keys [emoji-kb-extra-height]}
|
||||
{:keys [text-value]}
|
||||
{:keys [height saved-height]}
|
||||
{:keys [max-height]}]
|
||||
(let [start-h (oops/oget e "startCoordinates.height")
|
||||
end-h (oops/oget e "endCoordinates.height")
|
||||
diff (- end-h start-h)
|
||||
max (- max-height diff)
|
||||
curr-text @text-value]
|
||||
(if (> (reanimated/get-shared-value height) max)
|
||||
(do
|
||||
(reanimated/set-shared-value height (- (reanimated/get-shared-value height) diff))
|
||||
(reanimated/set-shared-value saved-height (- (reanimated/get-shared-value saved-height) diff))
|
||||
(reset! text-value (str @text-value " "))
|
||||
(js/setTimeout #(reset! text-value curr-text) 0)
|
||||
(reset! emoji-kb-extra-height diff))
|
||||
(when @emoji-kb-extra-height
|
||||
(reanimated/set-shared-value height
|
||||
(+ (reanimated/get-shared-value height) @emoji-kb-extra-height))
|
||||
(reanimated/set-shared-value saved-height
|
||||
(+ (reanimated/get-shared-value saved-height)
|
||||
@emoji-kb-extra-height))
|
||||
(reset! emoji-kb-extra-height nil)))))
|
||||
|
||||
(defn handle-kb-hide-android
|
||||
[{:keys [input-ref]}
|
||||
{:keys [opacity height saved-height background-y]}
|
||||
{:keys [window-height lines]}]
|
||||
(when platform/android?
|
||||
(let [min-height (get-min-height lines)]
|
||||
(.blur ^js @input-ref)
|
||||
(reanimated/animate opacity 0)
|
||||
(js/setTimeout (fn []
|
||||
(reanimated/animate height min-height)
|
||||
(reanimated/set-shared-value saved-height min-height)
|
||||
(reanimated/set-shared-value background-y (- window-height)))
|
||||
100))))
|
||||
|
||||
(defn handle-layout
|
||||
[e
|
||||
{:keys [lock-layout?]}
|
||||
@@ -445,50 +248,18 @@
|
||||
(when input-maximized?
|
||||
(reset! maximized? true)))
|
||||
|
||||
(defn store-kb-height
|
||||
[{:keys [kb-default-height]} keyboard-height]
|
||||
(when (and (not @kb-default-height) (pos? keyboard-height))
|
||||
(async-storage/set-item :kb-default-height keyboard-height)))
|
||||
(defn add-kb-listeners
|
||||
[{:keys [keyboard-show-listener keyboard-frame-listener keyboard-hide-listener] :as props}
|
||||
state animations dimensions keyboard-height]
|
||||
(reset! keyboard-show-listener (.addListener rn/keyboard
|
||||
"keyboardDidShow"
|
||||
#(store-kb-height state keyboard-height)))
|
||||
(reset! keyboard-frame-listener (.addListener
|
||||
rn/keyboard
|
||||
"keyboardWillChangeFrame"
|
||||
#(handle-emoji-kb-ios % props state animations dimensions)))
|
||||
(reset! keyboard-hide-listener (.addListener rn/keyboard
|
||||
"keyboardDidHide"
|
||||
#(handle-kb-hide-android props animations dimensions))))
|
||||
|
||||
(defn component-will-unmount
|
||||
[{:keys [keyboard-show-listener keyboard-hide-listener keyboard-frame-listener]}]
|
||||
(.remove ^js @keyboard-show-listener)
|
||||
(.remove ^js @keyboard-hide-listener)
|
||||
(.remove ^js @keyboard-frame-listener))
|
||||
|
||||
(defn gradient-components
|
||||
[{:keys [input-ref]}
|
||||
{:keys [gradient-z-index text-value focused?]}
|
||||
{:keys [gradient-opacity]}
|
||||
{:keys [lines]}]
|
||||
[:f>
|
||||
(fn []
|
||||
[:<>
|
||||
[reanimated/linear-gradient (style/top-gradient gradient-opacity @gradient-z-index)]
|
||||
(when (and (not-empty @text-value) (not @focused?) (> lines 2))
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press #(.focus ^js @input-ref)}
|
||||
[linear-gradient/linear-gradient (style/bottom-gradient)]])])])
|
||||
|
||||
(defn use-effect
|
||||
[props
|
||||
{:keys [lock-layout? kb-default-height maximized? text-value] :as state}
|
||||
{:keys [height saved-height container-opacity opacity background-y] :as animations}
|
||||
{:keys [max-height] :as dimensions}
|
||||
{:keys [input-content-height input-text] :as chat-input}
|
||||
{:keys [input-content-height] :as chat-input}
|
||||
keyboard-height images?]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
@@ -496,7 +267,7 @@
|
||||
(reanimated/animate height max-height)
|
||||
(reanimated/set-shared-value saved-height max-height))
|
||||
(handle-reenter-screen state dimensions chat-input)
|
||||
(when (nil? input-text)
|
||||
(when-not @lock-layout?
|
||||
(js/setTimeout #(reset! lock-layout? true) 500))
|
||||
(when-not @kb-default-height
|
||||
(async-storage/get-item :kb-default-height
|
||||
@@ -508,32 +279,12 @@
|
||||
(reanimated/animate container-opacity 1))
|
||||
(when (and (empty? @text-value) (not images?) (not @maximized?))
|
||||
(reanimated/animate-delay container-opacity 0.7 200))
|
||||
(add-kb-listeners props state animations dimensions keyboard-height)
|
||||
(kb/add-kb-listeners props state animations dimensions keyboard-height)
|
||||
#(component-will-unmount props))
|
||||
[max-height]))
|
||||
|
||||
(defn get-kb-height
|
||||
[curr-height default-height]
|
||||
(if (and default-height (< curr-height default-height))
|
||||
default-height
|
||||
curr-height))
|
||||
|
||||
(defn calc-lines
|
||||
[height]
|
||||
(let [lines (Math/round (/ height c/line-height))]
|
||||
(if platform/ios? lines (dec lines))))
|
||||
|
||||
(defn calc-max-height
|
||||
[window-height margin-top kb-height images]
|
||||
(let [max-height
|
||||
(- window-height margin-top kb-height c/handle-container-height c/actions-container-height)]
|
||||
(if (seq images)
|
||||
(- max-height c/images-container-height)
|
||||
max-height)))
|
||||
|
||||
;;; MAIN
|
||||
(defn sheet
|
||||
;; safe-area consumer insets makes incorrect values on Android
|
||||
[insets window-height layout-height opacity background-y]
|
||||
[:f>
|
||||
(fn []
|
||||
@@ -562,23 +313,23 @@
|
||||
content-height (reagent/atom (or input-content-height
|
||||
c/input-height))
|
||||
{:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard)
|
||||
kb-height (get-kb-height keyboard-height
|
||||
@(:kb-default-height state))
|
||||
max-height (calc-max-height window-height
|
||||
margin-top
|
||||
kb-height
|
||||
images)
|
||||
lines (calc-lines @content-height)
|
||||
max-lines (calc-lines max-height)
|
||||
kb-height (kb/get-kb-height keyboard-height
|
||||
@(:kb-default-height state))
|
||||
max-height (utils/calc-max-height window-height
|
||||
margin-top
|
||||
kb-height
|
||||
images)
|
||||
lines (utils/calc-lines @content-height)
|
||||
max-lines (utils/calc-lines max-height)
|
||||
initial-height (if (> lines 1)
|
||||
c/multiline-minimized-height
|
||||
c/input-height)
|
||||
animations {:gradient-opacity (reanimated/use-shared-value
|
||||
0)
|
||||
:container-opacity (reanimated/use-shared-value
|
||||
(if (and (nil? input-text)
|
||||
(not (seq
|
||||
images)))
|
||||
(if (utils/empty-input?
|
||||
input-text
|
||||
images)
|
||||
0.7
|
||||
1))
|
||||
:height (reanimated/use-shared-value
|
||||
@@ -586,7 +337,7 @@
|
||||
:saved-height (reanimated/use-shared-value
|
||||
initial-height)
|
||||
:last-height (reanimated/use-shared-value
|
||||
(bounded-val
|
||||
(utils/bounded-val
|
||||
@content-height
|
||||
c/input-height
|
||||
max-height))
|
||||
@@ -603,11 +354,10 @@
|
||||
[reanimated/view
|
||||
{:style (style/sheet-container insets (:container-opacity animations))
|
||||
:on-layout #(handle-layout % state layout-height)}
|
||||
[bar]
|
||||
[sub-view/bar]
|
||||
[reanimated/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:on-press #(.focus ^js @(:input-ref props)) ;; for android when first entering
|
||||
;; screen
|
||||
:on-press #(.focus ^js @(:input-ref props))
|
||||
:style (style/input-container (:height animations) max-height)}
|
||||
[rn/text-input
|
||||
{:ref #(reset! (:input-ref props) %)
|
||||
@@ -629,19 +379,11 @@
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
||||
:style (style/input @(:maximized? state)
|
||||
@(:saved-emoji-kb-extra-height props))}]
|
||||
[gradient-components props state animations dimensions]]
|
||||
[sub-view/gradients props state animations dimensions]]
|
||||
[images/images-list]
|
||||
[actions (:input-ref props) (:text-value state) (seq images) animations window-height
|
||||
[actions/view (:input-ref props) (:text-value state) (seq images) animations window-height
|
||||
insets]]]))]))])
|
||||
|
||||
|
||||
(defn blur-view
|
||||
[layout-height]
|
||||
[:f>
|
||||
(fn []
|
||||
[reanimated/view {:style (style/blur-container layout-height)}
|
||||
[blur/view style/blur-view]])])
|
||||
|
||||
(defn bottom-sheet-composer
|
||||
[]
|
||||
[:f>
|
||||
@@ -653,5 +395,5 @@
|
||||
layout-height (reanimated/use-shared-value (+ c/composer-default-height (:bottom insets)))]
|
||||
[rn/view
|
||||
[reanimated/view {:style (style/background opacity background-y window-height)}]
|
||||
[blur-view layout-height]
|
||||
[sub-view/blur-view layout-height]
|
||||
[sheet insets window-height layout-height opacity background-y]]))])
|
||||
|
||||
Reference in New Issue
Block a user