parent
7f50b56c26
commit
1d87957b04
|
@ -330,8 +330,8 @@ PODS:
|
|||
- SDWebImageWebPCoder (~> 0.8.4)
|
||||
- RNFS (2.16.6):
|
||||
- React
|
||||
- RNGestureHandler (1.8.0):
|
||||
- React
|
||||
- RNGestureHandler (2.5.0):
|
||||
- React-Core
|
||||
- RNHoleView (2.1.1):
|
||||
- React-Core
|
||||
- RNImageCropPicker (0.36.2):
|
||||
|
@ -691,7 +691,7 @@ SPEC CHECKSUMS:
|
|||
RNCPushNotificationIOS: c145c6253ea016e5efeff604f2720736b4a596f7
|
||||
RNFastImage: 1f2cab428712a4baaf78d6169eaec7f622556dd7
|
||||
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
|
||||
RNGestureHandler: 7a5833d0f788dbd107fbb913e09aa0c1ff333c39
|
||||
RNGestureHandler: bad495418bcbd3ab47017a38d93d290ebd406f50
|
||||
RNHoleView: 07572d21c97fad71fdc47f7248a8513e15a38949
|
||||
RNImageCropPicker: 35a3ceb837446fa11547704709bb22b5fac6d584
|
||||
RNKeychain: 216f37338fcb9e5c3a2530f1e3295f737a690cb1
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
"react-native-fast-image": "^8.5.11",
|
||||
"react-native-fetch-polyfill": "^1.1.2",
|
||||
"react-native-fs": "^2.14.1",
|
||||
"react-native-gesture-handler": "^1.8.0",
|
||||
"react-native-gesture-handler": "^2.5.0",
|
||||
"react-native-haptic-feedback": "^1.9.0",
|
||||
"react-native-hole-view": "git+https://github.com/status-im/react-native-hole-view.git#refs/tags/v2.1.1-status",
|
||||
"react-native-image-crop-picker": "git+https://github.com/status-im/react-native-image-crop-picker.git#refs/tags/v0.36.2-status.0",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 283 B |
Binary file not shown.
After Width: | Height: | Size: 343 B |
Binary file not shown.
After Width: | Height: | Size: 673 B |
Binary file not shown.
After Width: | Height: | Size: 964 B |
Binary file not shown.
After Width: | Height: | Size: 994 B |
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -219,6 +219,8 @@
|
|||
:FlatList #js {}
|
||||
:ScrollView #js {}
|
||||
:TouchableOpacity #js {}
|
||||
:GestureDetector #js {}
|
||||
:Gesture #js {:Pan nil}
|
||||
:createNativeWrapper identity})
|
||||
|
||||
(def react-native-redash #js {:clamp nil})
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
(ns quo.gesture-handler
|
||||
(:require [oops.core :refer [oget]]
|
||||
["react-native-reanimated" :default animated]
|
||||
[reagent.core :as reagent]
|
||||
[quo.design-system.colors :as colors]
|
||||
["react-native-gesture-handler"
|
||||
:refer (TapGestureHandler PanGestureHandler LongPressGestureHandler
|
||||
PureNativeButton TouchableWithoutFeedback TouchableOpacity
|
||||
TouchableHighlight
|
||||
createNativeWrapper State NativeViewGestureHandler
|
||||
TouchableWithoutFeedback TouchableOpacity
|
||||
TouchableHighlight State NativeViewGestureHandler
|
||||
FlatList ScrollView)]))
|
||||
|
||||
(def flat-list-raw FlatList)
|
||||
|
@ -25,8 +23,6 @@
|
|||
(def long-press-gesture-handler
|
||||
(reagent/adapt-react-class LongPressGestureHandler))
|
||||
|
||||
(def pure-native-button PureNativeButton)
|
||||
|
||||
(def touchable-without-feedback-class TouchableWithoutFeedback)
|
||||
|
||||
(def touchable-without-feedback
|
||||
|
@ -42,12 +38,6 @@
|
|||
(def touchable-opacity
|
||||
(reagent/adapt-react-class TouchableOpacity))
|
||||
|
||||
(def raw-button
|
||||
(reagent/adapt-react-class
|
||||
(createNativeWrapper (.createAnimatedComponent animated PureNativeButton)
|
||||
#js {:shouldActivateOnStart true
|
||||
:shouldCancelWhenOutside true})))
|
||||
|
||||
(def native-view-gesture-handler (reagent/adapt-react-class NativeViewGestureHandler))
|
||||
|
||||
(def states {:began (oget State "BEGAN")
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
(ns quo2.gesture
|
||||
(:require ["react-native-gesture-handler" :refer (GestureDetector Gesture)]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def gesture-detector (reagent/adapt-react-class GestureDetector))
|
||||
|
||||
(defn gesture-pan [] (.Pan ^js Gesture))
|
||||
|
||||
(defn on-update [^js pan handler] (.onUpdate pan handler))
|
||||
|
||||
(defn on-start [^js pan handler] (.onStart pan handler))
|
||||
|
||||
(defn on-end [^js pan handler] (.onEnd pan handler))
|
|
@ -3,7 +3,7 @@
|
|||
[reagent.core :as reagent]
|
||||
[clojure.string :as string]
|
||||
["react-native-reanimated" :default reanimated
|
||||
:refer (useSharedValue useAnimatedStyle withTiming withDelay Easing Keyframe)]))
|
||||
:refer (useSharedValue useAnimatedStyle withTiming withDelay withSpring Easing Keyframe)]))
|
||||
|
||||
;; Animated Components
|
||||
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated)))
|
||||
|
@ -19,6 +19,7 @@
|
|||
;; Animations
|
||||
(def with-timing withTiming)
|
||||
(def with-delay withDelay)
|
||||
(def with-spring withSpring)
|
||||
(def key-frame Keyframe)
|
||||
|
||||
;; Easings
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
(def switcher-bottom-positions
|
||||
{:android
|
||||
{:home-stack 15
|
||||
:chat 57}
|
||||
:chat 140}
|
||||
:ios
|
||||
{:home-stack 40
|
||||
:chat 67}})
|
||||
:chat 140}})
|
||||
|
||||
(defn switcher-bottom-position [view-id]
|
||||
(get-in
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
[status-im.switcher.animation :as animation]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.switcher.switcher-container :as switcher-container]))
|
||||
[status-im.switcher.switcher-container :as switcher-container]
|
||||
[quo.react-native :as rn]))
|
||||
|
||||
(defn switcher-button [view-id toggle-switcher-screen-fn shared-values]
|
||||
[:f>
|
||||
|
@ -71,7 +72,9 @@
|
|||
:switcher-container-scale (reanimated/use-shared-value 0.9)
|
||||
:close-button-opacity (animation/switcher-close-button-opacity switcher-button-opacity)
|
||||
:switcher-container-bottom (animation/switcher-container-bottom-position switcher-screen-bottom)}
|
||||
toggle-switcher-screen-fn #(animation/switcher-touchable-on-press-out switcher-opened? view-id shared-values)]
|
||||
[:<>
|
||||
[switcher-screen toggle-switcher-screen-fn shared-values]
|
||||
[switcher-button view-id toggle-switcher-screen-fn shared-values]]))])
|
||||
toggle-switcher-screen-fn #(animation/switcher-touchable-on-press-out switcher-opened? view-id shared-values)
|
||||
{:keys [keyboard-shown]} (rn/use-keyboard)]
|
||||
(when-not keyboard-shown
|
||||
[:<>
|
||||
[switcher-screen toggle-switcher-screen-fn shared-values]
|
||||
[switcher-button view-id toggle-switcher-screen-fn shared-values]])))])
|
||||
|
|
|
@ -248,6 +248,14 @@
|
|||
(update props :keyboardVerticalOffset + 44 (:status-bar-height @navigation-const))))]
|
||||
children))
|
||||
|
||||
(defn keyboard-avoiding-view-new [props & children]
|
||||
(into [keyboard-avoiding-view-class
|
||||
(merge (when platform/ios? {:behavior :padding})
|
||||
(if (:ignore-offset props)
|
||||
props
|
||||
(update props :keyboardVerticalOffset + 44)))]
|
||||
children))
|
||||
|
||||
(defn scroll-view [props & children]
|
||||
(vec (conj children props scroll-view-class)))
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.ui.screens.chat.components.input
|
||||
(:require [status-im.ui.components.icons.icons :as icons]
|
||||
[quo.react-native :as rn]
|
||||
[oops.core :refer [oget]]
|
||||
[quo.react :as react]
|
||||
[quo.platform :as platform]
|
||||
[quo.components.text :as text]
|
||||
|
@ -19,7 +20,11 @@
|
|||
[quo.components.list.item :as list-item]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[reagent.core :as reagent]
|
||||
[clojure.string :as string]))
|
||||
[clojure.string :as string]
|
||||
[quo2.components.button :as quo2.button]
|
||||
[quo2.reanimated :as reanimated]
|
||||
[quo2.gesture :as gesture]
|
||||
[quo.components.safe-area :as safe-area]))
|
||||
|
||||
(defn input-focus [text-input-ref]
|
||||
(some-> ^js (react/current-ref text-input-ref) .focus))
|
||||
|
@ -58,8 +63,9 @@
|
|||
:on-denied
|
||||
#(utils.utils/set-timeout
|
||||
(fn []
|
||||
(utils.utils/show-popup (i18n/label :t/audio-recorder-error)
|
||||
(i18n/label :t/audio-recorder-permissions-error)))
|
||||
(utils.utils/show-popup
|
||||
(i18n/label :t/audio-recorder-error)
|
||||
(i18n/label :t/audio-recorder-permissions-error)))
|
||||
50)}]))
|
||||
|
||||
(defn touchable-audio-icon [{:keys [panel active set-active accessibility-label input-focus]}]
|
||||
|
@ -82,6 +88,15 @@
|
|||
:accessibility-label :send-message-button
|
||||
:color (styles/send-icon-color)}])]])
|
||||
|
||||
(defn send-button-old [on-send contact-request]
|
||||
[rn/touchable-opacity {:on-press-in on-send}
|
||||
[rn/view {:style (styles/send-message-button)}
|
||||
(when-not contact-request
|
||||
[icons/icon :main-icons/arrow-up
|
||||
{:container-style (styles/send-message-container contact-request)
|
||||
:accessibility-label :send-message-button
|
||||
:color (styles/send-icon-color)}])]])
|
||||
|
||||
(defn on-selection-change [timeout-id last-text-change mentionable-users args]
|
||||
(let [selection (.-selection ^js (.-nativeEvent ^js args))
|
||||
start (.-start selection)
|
||||
|
@ -128,14 +143,18 @@
|
|||
(swap! chat-input-key inc))
|
||||
|
||||
(defn show-send [{:keys [actions-ref send-ref sticker-ref]}]
|
||||
(quo.react/set-native-props actions-ref #js {:width 0 :left -88})
|
||||
(when actions-ref
|
||||
(quo.react/set-native-props actions-ref #js {:width 0 :left -88}))
|
||||
(quo.react/set-native-props send-ref #js {:width nil :right nil})
|
||||
(quo.react/set-native-props sticker-ref #js {:width 0 :right -100}))
|
||||
(when sticker-ref
|
||||
(quo.react/set-native-props sticker-ref #js {:width 0 :right -100})))
|
||||
|
||||
(defn hide-send [{:keys [actions-ref send-ref sticker-ref]}]
|
||||
(quo.react/set-native-props actions-ref #js {:width nil :left nil})
|
||||
(when actions-ref
|
||||
(quo.react/set-native-props actions-ref #js {:width nil :left nil}))
|
||||
(quo.react/set-native-props send-ref #js {:width 0 :right -100})
|
||||
(quo.react/set-native-props sticker-ref #js {:width nil :right nil}))
|
||||
(when sticker-ref
|
||||
(quo.react/set-native-props sticker-ref #js {:width nil :right nil})))
|
||||
|
||||
(defn reset-input [refs chat-id]
|
||||
(some-> ^js (react/current-ref (:text-input-ref refs)) .clear)
|
||||
|
@ -235,7 +254,7 @@
|
|||
(when platform/android?
|
||||
(re-frame/dispatch [::mentions/calculate-suggestions mentionable-users]))))
|
||||
|
||||
(defn text-input [{:keys [set-active-panel refs chat-id sending-image]}]
|
||||
(defn text-input-old [{:keys [set-active-panel refs chat-id sending-image]}]
|
||||
(let [cooldown-enabled? @(re-frame/subscribe [:chats/cooldown-enabled?])
|
||||
mentionable-users @(re-frame/subscribe [:chats/mentionable-users])
|
||||
timeout-id (atom nil)
|
||||
|
@ -244,7 +263,7 @@
|
|||
contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
|
||||
|
||||
[rn/text-input
|
||||
{:style (styles/text-input contact-request)
|
||||
{:style (styles/text-input-old contact-request)
|
||||
:ref (:text-input-ref refs)
|
||||
:max-font-size-multiplier 1
|
||||
:accessibility-label :chat-message-input
|
||||
|
@ -274,6 +293,47 @@
|
|||
text])
|
||||
(get @input-texts chat-id))]))
|
||||
|
||||
(defn text-input [{:keys [set-active-panel refs chat-id sending-image on-content-size-change]}]
|
||||
(let [cooldown-enabled? @(re-frame/subscribe [:chats/cooldown-enabled?])
|
||||
mentionable-users @(re-frame/subscribe [:chats/mentionable-users])
|
||||
timeout-id (atom nil)
|
||||
last-text-change (atom nil)
|
||||
mentions-enabled (get @mentions-enabled chat-id)]
|
||||
|
||||
[rn/text-input
|
||||
{:style (styles/text-input)
|
||||
:ref (:text-input-ref refs)
|
||||
:max-font-size-multiplier 1
|
||||
:accessibility-label :chat-message-input
|
||||
:text-align-vertical :center
|
||||
:multiline true
|
||||
:editable (not cooldown-enabled?)
|
||||
:blur-on-submit false
|
||||
:auto-focus false
|
||||
:on-focus #(set-active-panel nil)
|
||||
:max-length chat.constants/max-text-size
|
||||
:placeholder-text-color (:text-02 @colors/theme)
|
||||
:placeholder (if cooldown-enabled?
|
||||
(i18n/label :cooldown/text-input-disabled)
|
||||
(i18n/label :t/type-a-message))
|
||||
:underline-color-android :transparent
|
||||
:auto-capitalize :sentences
|
||||
:auto-correct false
|
||||
:spell-check false
|
||||
:on-content-size-change on-content-size-change
|
||||
:on-selection-change (partial on-selection-change timeout-id last-text-change mentionable-users)
|
||||
:on-change (partial on-change last-text-change timeout-id mentionable-users refs chat-id sending-image)
|
||||
:on-text-input (partial on-text-input mentionable-users chat-id)}
|
||||
(if mentions-enabled
|
||||
(for [[idx [type text]] (map-indexed
|
||||
(fn [idx item]
|
||||
[idx item])
|
||||
@(re-frame/subscribe [:chat/input-with-mentions]))]
|
||||
^{:key (str idx "_" type "_" text)}
|
||||
[rn/text (when (= type :mention) {:style {:color "#0DA4C9"}})
|
||||
text])
|
||||
(get @input-texts chat-id))]))
|
||||
|
||||
(defn mention-item
|
||||
[[public-key {:keys [alias name nickname] :as user}] _ _ text-input-ref]
|
||||
(let [ens-name? (not= alias name)]
|
||||
|
@ -350,12 +410,12 @@
|
|||
:active active-panel
|
||||
:set-active set-active-panel}])])
|
||||
|
||||
(defn chat-toolbar [{:keys [chat-id]}]
|
||||
(let [actions-ref (quo.react/create-ref)
|
||||
send-ref (quo.react/create-ref)
|
||||
sticker-ref (quo.react/create-ref)
|
||||
(defn chat-toolbar-old [{:keys [chat-id]}]
|
||||
(let [actions-ref (quo.react/create-ref)
|
||||
send-ref (quo.react/create-ref)
|
||||
sticker-ref (quo.react/create-ref)
|
||||
toolbar-options (re-frame/subscribe [:chats/chat-toolbar])
|
||||
show-send (seq (get @input-texts chat-id))]
|
||||
show-send (seq (get @input-texts chat-id))]
|
||||
(fn [{:keys [active-panel set-active-panel text-input-ref chat-id]}]
|
||||
(let [;we want to control components on native level, so instead of RN state we set native props via reference
|
||||
;we don't react on input text in this view, @input-texts below is a regular atom
|
||||
|
@ -364,24 +424,24 @@
|
|||
:sticker-ref sticker-ref
|
||||
:text-input-ref text-input-ref}
|
||||
{:keys [send stickers image extensions audio sending-image]} @toolbar-options
|
||||
show-send (or show-send sending-image)
|
||||
show-send (or show-send sending-image)
|
||||
contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
|
||||
[rn/view {:style (styles/toolbar)
|
||||
:on-layout on-chat-toolbar-layout}
|
||||
;;EXTENSIONS and IMAGE buttons
|
||||
;;EXTENSIONS and IMAGE buttons
|
||||
[actions extensions image show-send actions-ref active-panel set-active-panel contact-request]
|
||||
[rn/view {:style (styles/input-container contact-request)}
|
||||
[send-image]
|
||||
[rn/view {:style styles/input-row}
|
||||
[text-input {:chat-id chat-id
|
||||
:sending-image sending-image
|
||||
:refs refs
|
||||
:set-active-panel set-active-panel}]
|
||||
[text-input-old {:chat-id chat-id
|
||||
:sending-image sending-image
|
||||
:refs refs
|
||||
:set-active-panel set-active-panel}]
|
||||
;;SEND button
|
||||
[rn/view {:ref send-ref :style (when-not show-send {:width 0 :right -100})}
|
||||
(when send
|
||||
[send-button #(do (clear-input chat-id refs)
|
||||
(re-frame/dispatch [:chat.ui/send-current-message]))
|
||||
[send-button-old #(do (clear-input chat-id refs)
|
||||
(re-frame/dispatch [:chat.ui/send-current-message]))
|
||||
contact-request])]
|
||||
|
||||
;;STICKERS and AUDIO buttons
|
||||
|
@ -400,3 +460,163 @@
|
|||
:active active-panel
|
||||
:input-focus #(input-focus text-input-ref)
|
||||
:set-active set-active-panel}])])]]]))))
|
||||
|
||||
(defn calculate-y [context keyboard-shown min-y max-y]
|
||||
(if keyboard-shown
|
||||
(if (= (:state @context) :max)
|
||||
max-y
|
||||
(if (< (:y @context) max-y)
|
||||
(:y @context)
|
||||
(do
|
||||
(swap! context assoc :state :max)
|
||||
max-y)))
|
||||
(do
|
||||
(swap! context assoc :state :min)
|
||||
min-y)))
|
||||
|
||||
(defn get-bottom-sheet-gesture [context translate-y text-input-ref keyboard-shown min-y max-y shared-height max-height bg-opacity]
|
||||
(-> (gesture/gesture-pan)
|
||||
(gesture/on-start
|
||||
(fn [_]
|
||||
(if keyboard-shown
|
||||
(swap! context assoc :pan-y (reanimated/get-shared-value translate-y))
|
||||
(input-focus text-input-ref))))
|
||||
(gesture/on-update
|
||||
(fn [evt]
|
||||
(when keyboard-shown
|
||||
(swap! context assoc :dy (- (.-translationY evt) (:pdy @context)))
|
||||
(swap! context assoc :pdy (.-translationY evt))
|
||||
(reanimated/set-shared-value
|
||||
translate-y
|
||||
(max (min (+ (.-translationY evt) (:pan-y @context)) (- min-y)) (- max-y))))))
|
||||
(gesture/on-end
|
||||
(fn [_]
|
||||
(when keyboard-shown
|
||||
(if (< (:dy @context) 0)
|
||||
(do
|
||||
(swap! context assoc :state :max)
|
||||
(input-focus text-input-ref)
|
||||
(reanimated/set-shared-value translate-y (reanimated/with-timing (- max-y)))
|
||||
(reanimated/set-shared-value shared-height (reanimated/with-timing max-height))
|
||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing 1)))
|
||||
(do
|
||||
(swap! context assoc :state :min)
|
||||
(reanimated/set-shared-value translate-y (reanimated/with-timing (- min-y)))
|
||||
(reanimated/set-shared-value shared-height (reanimated/with-timing min-y))
|
||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing 0))
|
||||
(re-frame/dispatch [:dismiss-keyboard]))))))))
|
||||
|
||||
(defn get-input-content-change [context translate-y shared-height max-height bg-opacity keyboard-shown min-y max-y]
|
||||
(fn [evt]
|
||||
(if (:clear @context)
|
||||
(do
|
||||
(swap! context dissoc :clear)
|
||||
(swap! context assoc :state :min)
|
||||
(swap! context assoc :y min-y)
|
||||
(reanimated/set-shared-value translate-y (reanimated/with-timing (- min-y)))
|
||||
(reanimated/set-shared-value shared-height (reanimated/with-timing min-y))
|
||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing 0)))
|
||||
(when (not= (:state @context) :max)
|
||||
(let [new-y (+ min-y (- (max (oget evt "nativeEvent" "contentSize" "height") 22) 22))]
|
||||
(if (< new-y max-y)
|
||||
(do
|
||||
(if (> (- max-y new-y) 120)
|
||||
(do
|
||||
(swap! context assoc :state :custom-chat-available)
|
||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing 0)))
|
||||
(do
|
||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing 1))
|
||||
(swap! context assoc :state :custom-chat-unavailable)))
|
||||
(swap! context assoc :y new-y)
|
||||
(when keyboard-shown
|
||||
(reanimated/set-shared-value
|
||||
translate-y
|
||||
(reanimated/with-timing (- new-y)))
|
||||
(reanimated/set-shared-value
|
||||
shared-height
|
||||
(reanimated/with-timing (min new-y max-height)))))
|
||||
(do
|
||||
(swap! context assoc :state :max)
|
||||
(swap! context assoc :y max-y)
|
||||
(when keyboard-shown
|
||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing 1))
|
||||
(reanimated/set-shared-value
|
||||
translate-y
|
||||
(reanimated/with-timing (- max-y)))))))))))
|
||||
|
||||
(defn chat-input-bottom-sheet [chat-id]
|
||||
[safe-area/consumer
|
||||
(fn [insets]
|
||||
(let [min-y 112
|
||||
context (atom {:y min-y ;current y value
|
||||
:min-y min-y ;minimum y value
|
||||
:dy 0 ;used for gesture
|
||||
:pdy 0 ;used for gesture
|
||||
:state :min ;:min, :custom-chat-available, :custom-chat-unavailable, :max
|
||||
:clear false})
|
||||
keyboard-was-shown (atom false)]
|
||||
(fn []
|
||||
[:f>
|
||||
(fn []
|
||||
(let [text-input-ref (quo.react/create-ref)
|
||||
send-ref (quo.react/create-ref)
|
||||
refs {:send-ref send-ref
|
||||
:text-input-ref text-input-ref}
|
||||
|
||||
{window-height :height} (rn/use-window-dimensions)
|
||||
{:keys [keyboard-shown keyboard-height]} (rn/use-keyboard)
|
||||
|
||||
max-y (- window-height (if (> keyboard-height 0) keyboard-height 360) (:top insets)) ; 360 - defaul height
|
||||
max-height (- max-y 56 (:bottom insets)) ; 56 - topbar height
|
||||
y (calculate-y context keyboard-shown min-y max-y)
|
||||
|
||||
translate-y (reanimated/use-shared-value 0)
|
||||
shared-height (reanimated/use-shared-value min-y)
|
||||
bg-opacity (reanimated/use-shared-value 0)
|
||||
|
||||
bottom-sheet-gesture (get-bottom-sheet-gesture context translate-y text-input-ref keyboard-shown
|
||||
min-y max-y shared-height max-height bg-opacity)
|
||||
input-content-change (get-input-content-change context translate-y shared-height max-height
|
||||
bg-opacity keyboard-shown min-y max-y)]
|
||||
(quo.react/effect! #(do
|
||||
(when (and @keyboard-was-shown (not keyboard-shown))
|
||||
(swap! context assoc :state :min))
|
||||
(reset! keyboard-was-shown keyboard-shown)
|
||||
(if (#{:max :custom-chat-unavailable} (:state @context))
|
||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing 1))
|
||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing 0)))
|
||||
(reanimated/set-shared-value translate-y (reanimated/with-timing (- y)))
|
||||
(reanimated/set-shared-value shared-height (reanimated/with-timing (min y max-height)))))
|
||||
[reanimated/view {:style (reanimated/apply-animations-to-style
|
||||
{:height shared-height}
|
||||
{})}
|
||||
;;INPUT MESSAGE bottom sheet
|
||||
[gesture/gesture-detector {:gesture bottom-sheet-gesture}
|
||||
[reanimated/view {:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
(styles/new-input-bottom-sheet window-height))}
|
||||
;handle
|
||||
[rn/view {:style (styles/new-bottom-sheet-handle)}]
|
||||
[rn/view {:style {:height (- max-y 80)}}
|
||||
[text-input {:chat-id chat-id
|
||||
:on-content-size-change input-content-change
|
||||
:sending-image false
|
||||
:refs refs
|
||||
:set-active-panel #()}]]]]
|
||||
;CONTROLS
|
||||
[rn/view {:style (styles/new-bottom-sheet-controls insets)}
|
||||
[quo2.button/button {:icon true :type :outline :size 32} :main-icons2/image]
|
||||
[rn/view {:width 12}]
|
||||
[quo2.button/button {:icon true :type :outline :size 32} :main-icons2/reaction]
|
||||
[rn/view {:flex 1}]
|
||||
;;SEND button
|
||||
[rn/view {:ref send-ref :style (when-not (seq (get @input-texts chat-id)) {:width 0 :right -100})}
|
||||
[quo2.button/button {:icon true :size 32 :accessibility-label :send-message-button
|
||||
:on-press #(do (swap! context assoc :clear true)
|
||||
(clear-input chat-id refs)
|
||||
(re-frame/dispatch [:chat.ui/send-current-message]))}
|
||||
:main-icons2/arrow-up]]]
|
||||
;black background
|
||||
[reanimated/view {:style (reanimated/apply-animations-to-style
|
||||
{:opacity bg-opacity}
|
||||
(styles/new-bottom-sheet-background window-height))}]]))])))])
|
|
@ -1,7 +1,9 @@
|
|||
(ns status-im.ui.screens.chat.components.style
|
||||
(:require [quo.platform :as platform]
|
||||
[quo.design-system.colors :as colors]
|
||||
[quo.design-system.typography :as typography]))
|
||||
[quo.design-system.typography :as typography]
|
||||
[quo2.foundations.colors :as quo2.colors]
|
||||
[quo2.foundations.typography :as quo2.typography]))
|
||||
|
||||
(defn toolbar []
|
||||
{:min-height 52
|
||||
|
@ -35,7 +37,7 @@
|
|||
(when platform/ios?
|
||||
{:padding-top 2})))
|
||||
|
||||
(defn text-input [contact-request]
|
||||
(defn text-input-old [contact-request]
|
||||
(merge typography/font-regular
|
||||
typography/base
|
||||
{:flex 1
|
||||
|
@ -50,13 +52,27 @@
|
|||
{:padding-top (if contact-request 10 2)
|
||||
:padding-bottom (if contact-request 5 6)})))
|
||||
|
||||
(defn text-input []
|
||||
(merge quo2.typography/font-regular
|
||||
quo2.typography/paragraph-1
|
||||
{:flex 1
|
||||
:min-height 34
|
||||
:margin 0
|
||||
:flex-shrink 1
|
||||
:color (:text-01 @colors/theme)
|
||||
:margin-horizontal 20}
|
||||
(if platform/android?
|
||||
{:padding-vertical 8
|
||||
:text-align-vertical :top}
|
||||
{:margin-top 8
|
||||
:margin-bottom 8})))
|
||||
|
||||
(defn actions-wrapper [show-send]
|
||||
(merge
|
||||
(when show-send
|
||||
{:width 0 :left -88})
|
||||
{:flex-direction :row
|
||||
:padding-left 4
|
||||
:min-height 34}))
|
||||
(merge (when show-send
|
||||
{:width 0 :left -88})
|
||||
{:flex-direction :row
|
||||
:padding-left 4
|
||||
:min-height 34}))
|
||||
|
||||
(defn touchable-icon []
|
||||
{:padding-horizontal 10
|
||||
|
@ -85,7 +101,7 @@
|
|||
:background-color (:ui-03 @colors/theme)})
|
||||
|
||||
(defn reply-container []
|
||||
{:flex-direction :row})
|
||||
{:flex-direction :row})
|
||||
|
||||
(defn reply-content-old []
|
||||
{:padding-vertical 6
|
||||
|
@ -98,9 +114,9 @@
|
|||
:flex-direction :row})
|
||||
|
||||
(defn contact-request-content []
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:justify-content :space-between})
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:justify-content :space-between})
|
||||
|
||||
(defn close-button []
|
||||
{:margin-top 3})
|
||||
|
@ -128,3 +144,52 @@
|
|||
:background-color (colors/get-color :ui-background)
|
||||
:border-top-width 1
|
||||
:border-top-color (colors/get-color :ui-01)})
|
||||
|
||||
(defn new-input-bottom-sheet [window-height]
|
||||
(merge {:border-top-left-radius 20
|
||||
:border-top-right-radius 20
|
||||
:position :absolute
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom (- window-height)
|
||||
:height window-height
|
||||
:flex 1
|
||||
:background-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/neutral-90)
|
||||
:z-index 1000}
|
||||
(if platform/ios?
|
||||
{:shadow-radius 16
|
||||
:shadow-opacity 1
|
||||
:shadow-color "rgba(9, 16, 28, 0.04)"
|
||||
:shadow-offset {:width 0 :height -2}}
|
||||
{:elevation 2})))
|
||||
|
||||
(defn new-bottom-sheet-handle []
|
||||
{:width 32
|
||||
:height 4
|
||||
:background-color (quo2.colors/theme-colors quo2.colors/black quo2.colors/white)
|
||||
:opacity 0.05
|
||||
:border-radius 100
|
||||
:align-self :center
|
||||
:margin-top 8})
|
||||
|
||||
(defn new-bottom-sheet-controls [insets]
|
||||
{:flex-direction :row
|
||||
:padding-horizontal 20
|
||||
:elevation 2
|
||||
:z-index 2000
|
||||
:position :absolute
|
||||
:background-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/neutral-90)
|
||||
;these 3 props play together, we need this magic to hide message text in the safe area
|
||||
:padding-top 10
|
||||
:padding-bottom (+ 12 (:bottom insets))
|
||||
:bottom (- 2 (:bottom insets))})
|
||||
|
||||
(defn new-bottom-sheet-background [window-height]
|
||||
{:pointerEvents :none
|
||||
:position :absolute
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0
|
||||
:height window-height
|
||||
:background-color quo2.colors/neutral-95-opa-70
|
||||
:z-index 500})
|
|
@ -85,23 +85,23 @@
|
|||
(let [contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
|
||||
[react/view {:style style/contact-request}
|
||||
[react/image {:source (resources/get-image :hand-wave)
|
||||
:style {:width 112
|
||||
:height 96.71
|
||||
:style {:width 112
|
||||
:height 96.71
|
||||
:margin-top 17}}]
|
||||
[quo/text {:style {:margin-top 14}
|
||||
[quo/text {:style {:margin-top 14}
|
||||
:weight :bold
|
||||
:size :large}
|
||||
(i18n/label :t/say-hi)]
|
||||
[quo/text {:style {:margin-top 2
|
||||
[quo/text {:style {:margin-top 2
|
||||
:margin-bottom 14}}
|
||||
(i18n/label :t/send-contact-request-message)]
|
||||
(when-not contact-request
|
||||
[react/view {:style {:padding-horizontal 16
|
||||
:padding-bottom 8}}
|
||||
:padding-bottom 8}}
|
||||
[quo/button
|
||||
{:style {:width "100%"}
|
||||
{:style {:width "100%"}
|
||||
:accessibility-label :contact-request--button
|
||||
:on-press #(re-frame/dispatch [:chat.ui/send-contact-request])}
|
||||
:on-press #(re-frame/dispatch [:chat.ui/send-contact-request])}
|
||||
(i18n/label :t/contact-request)]])]))
|
||||
|
||||
(defn chat-intro [{:keys [chat-id
|
||||
|
@ -116,7 +116,7 @@
|
|||
no-messages?
|
||||
contact-request-state
|
||||
emoji]}]
|
||||
[react/view {:style (style/intro-header-container loading-messages? no-messages?)
|
||||
[react/view {:style (style/intro-header-container loading-messages? no-messages?)
|
||||
:accessibility-label :history-chat}
|
||||
;; Icon section
|
||||
[react/view {:style {:margin-top 52
|
||||
|
@ -133,34 +133,25 @@
|
|||
(if group-chat chat-name contact-name)]
|
||||
;; Description section
|
||||
(if group-chat
|
||||
[chat.group/group-chat-description-container {:chat-id chat-id
|
||||
:invitation-admin invitation-admin
|
||||
[chat.group/group-chat-description-container {:chat-id chat-id
|
||||
:invitation-admin invitation-admin
|
||||
:loading-messages? loading-messages?
|
||||
:chat-name chat-name
|
||||
:chat-type chat-type
|
||||
:no-messages? no-messages?}]
|
||||
[react/text {:style (assoc style/intro-header-description
|
||||
:margin-bottom 32)}
|
||||
|
||||
(str
|
||||
(i18n/label :t/empty-chat-description-one-to-one)
|
||||
contact-name)])
|
||||
(when
|
||||
(and
|
||||
mutual-contact-requests-enabled?
|
||||
(= chat-type constants/one-to-one-chat-type)
|
||||
(or
|
||||
(= contact-request-state constants/contact-request-state-none)
|
||||
(= contact-request-state constants/contact-request-state-received)
|
||||
(= contact-request-state constants/contact-request-state-dismissed)))
|
||||
:chat-name chat-name
|
||||
:chat-type chat-type
|
||||
:no-messages? no-messages?}]
|
||||
[react/text {:style (assoc style/intro-header-description :margin-bottom 32)}
|
||||
(str (i18n/label :t/empty-chat-description-one-to-one) contact-name)])
|
||||
(when (and mutual-contact-requests-enabled?
|
||||
(= chat-type constants/one-to-one-chat-type)
|
||||
(or (= contact-request-state constants/contact-request-state-none)
|
||||
(= contact-request-state constants/contact-request-state-received)
|
||||
(= contact-request-state constants/contact-request-state-dismissed)))
|
||||
[contact-request])])
|
||||
|
||||
(defn chat-intro-one-to-one [{:keys [chat-id] :as opts}]
|
||||
(let [contact @(re-frame/subscribe
|
||||
[:contacts/contact-by-identity chat-id])
|
||||
(let [contact @(re-frame/subscribe [:contacts/contact-by-identity chat-id])
|
||||
mutual-contact-requests-enabled? @(re-frame/subscribe [:mutual-contact-requests/enabled?])
|
||||
contact-names @(re-frame/subscribe
|
||||
[:contacts/contact-two-names-by-identity chat-id])]
|
||||
contact-names @(re-frame/subscribe [:contacts/contact-two-names-by-identity chat-id])]
|
||||
[chat-intro (assoc opts
|
||||
:mutual-contact-requests-enabled? mutual-contact-requests-enabled?
|
||||
:contact-name (first contact-names)
|
||||
|
@ -175,21 +166,21 @@
|
|||
public? emoji]}
|
||||
no-messages]
|
||||
[react/touchable-without-feedback
|
||||
{:style {:flex 1
|
||||
:align-items :flex-start}
|
||||
{:style {:flex 1
|
||||
:align-items :flex-start}
|
||||
:on-press (fn [_]
|
||||
(react/dismiss-keyboard!))}
|
||||
(let [opts
|
||||
{:chat-id chat-id
|
||||
:group-chat group-chat
|
||||
:invitation-admin invitation-admin
|
||||
:chat-type chat-type
|
||||
:chat-name chat-name
|
||||
:public? public?
|
||||
:color color
|
||||
{:chat-id chat-id
|
||||
:group-chat group-chat
|
||||
:invitation-admin invitation-admin
|
||||
:chat-type chat-type
|
||||
:chat-name chat-name
|
||||
:public? public?
|
||||
:color color
|
||||
:loading-messages? (not (pos? synced-to))
|
||||
:no-messages? no-messages
|
||||
:emoji emoji}]
|
||||
:no-messages? no-messages
|
||||
:emoji emoji}]
|
||||
(if group-chat
|
||||
[chat-intro opts]
|
||||
[chat-intro-one-to-one opts]))])
|
||||
|
@ -241,15 +232,15 @@
|
|||
[toolbar/toolbar {:show-border? true
|
||||
:right
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
{:type :secondary
|
||||
:accessibility-label :retry-button
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/membership-retry])}
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/membership-retry])}
|
||||
(i18n/label :t/mailserver-retry)]
|
||||
:left
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
{:type :secondary
|
||||
:accessibility-label :remove-group-button
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/remove-chat-confirmed chat-id])}
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/remove-chat-confirmed chat-id])}
|
||||
(i18n/label :t/remove-group)]}]
|
||||
:else
|
||||
[toolbar/toolbar {:show-border? true
|
||||
|
@ -442,7 +433,7 @@
|
|||
(let [{:keys [group-chat chat-type chat-id public? community-id admins]} chat
|
||||
|
||||
messages @(re-frame/subscribe [:chats/raw-chat-messages-stream chat-id])
|
||||
one-to-one? (= chat-type constants/one-to-one-chat-type)
|
||||
one-to-one? (= chat-type constants/one-to-one-chat-type)
|
||||
contact-added? (when one-to-one? @(re-frame/subscribe [:contacts/contact-added? chat-id]))
|
||||
should-send-contact-request?
|
||||
(and
|
||||
|
@ -473,9 +464,9 @@
|
|||
:on-viewable-items-changed on-viewable-items-changed
|
||||
:on-end-reached list-on-end-reached
|
||||
:on-scroll-to-index-failed identity ;;don't remove this
|
||||
:content-container-style {:padding-top (+ bottom-space 16)
|
||||
:content-container-style {:padding-top (+ bottom-space 16)
|
||||
:padding-bottom 16}
|
||||
:scroll-indicator-insets {:top bottom-space} ;;ios only
|
||||
:scroll-indicator-insets {:top bottom-space} ;;ios only
|
||||
:keyboard-dismiss-mode :interactive
|
||||
:keyboard-should-persist-taps :handled
|
||||
:onMomentumScrollBegin state/start-scrolling
|
||||
|
@ -525,10 +516,10 @@
|
|||
(defn topbar-old []
|
||||
;;we don't use topbar component, because we want chat view as simple (fast) as possible
|
||||
[react/view {:height 56}
|
||||
[react/touchable-highlight {:on-press-in navigate-back-handler
|
||||
[react/touchable-highlight {:on-press-in navigate-back-handler
|
||||
:accessibility-label :back-button
|
||||
:style {:height 56 :width 40 :align-items :center :justify-content :center
|
||||
:padding-left 16}}
|
||||
:style {:height 56 :width 40 :align-items :center :justify-content :center
|
||||
:padding-left 16}}
|
||||
[icons/icon :main-icons/arrow-left {:color colors/black}]]
|
||||
[react/view {:flex 1 :left 52 :right 52 :top 0 :bottom 0 :position :absolute}
|
||||
[topbar-content-old]]
|
||||
|
@ -537,9 +528,9 @@
|
|||
[sheets/current-chat-actions])
|
||||
:height 256}])
|
||||
:accessibility-label :chat-menu-button
|
||||
:style {:right 0 :top 0 :bottom 0 :position :absolute
|
||||
:height 56 :width 40 :align-items :center :justify-content :center
|
||||
:padding-right 16}}
|
||||
:style {:right 0 :top 0 :bottom 0 :position :absolute
|
||||
:height 56 :width 40 :align-items :center :justify-content :center
|
||||
:padding-right 16}}
|
||||
[icons/icon :main-icons/more {:color colors/black}]]])
|
||||
|
||||
(defn chat-render-old []
|
||||
|
@ -592,7 +583,7 @@
|
|||
;; We set the key so we can force a re-render as
|
||||
;; it does not rely on ratom but just atoms
|
||||
^{:key (str @components/chat-input-key "chat-input")}
|
||||
[components/chat-toolbar
|
||||
[components/chat-toolbar-old
|
||||
{:chat-id chat-id
|
||||
:active-panel @active-panel
|
||||
:set-active-panel set-active-panel
|
||||
|
@ -601,70 +592,33 @@
|
|||
[bottom-sheet @active-panel]])]))))
|
||||
|
||||
(defn chat-render []
|
||||
(let [bottom-space (reagent/atom 0)
|
||||
panel-space (reagent/atom 52)
|
||||
active-panel (reagent/atom nil)
|
||||
position-y (animated/value 0)
|
||||
pan-state (animated/value 0)
|
||||
text-input-ref (quo.react/create-ref)
|
||||
on-update #(when-not (zero? %) (reset! panel-space %))
|
||||
pan-responder (accessory/create-pan-responder position-y pan-state)
|
||||
space-keeper (get-space-keeper-ios bottom-space panel-space active-panel text-input-ref)
|
||||
set-active-panel (get-set-active-panel active-panel)
|
||||
on-close #(set-active-panel nil)]
|
||||
(fn []
|
||||
(let [{:keys [chat-id show-input? group-chat admins invitation-admin] :as chat}
|
||||
;;we want to react only on these fields, do not use full chat map here
|
||||
@(re-frame/subscribe [:chats/current-chat-chat-view])
|
||||
mutual-contact-requests-enabled? @(re-frame/subscribe [:mutual-contact-requests/enabled?])
|
||||
max-bottom-space (max @bottom-space @panel-space)]
|
||||
[:<>
|
||||
;; It is better to not use topbar component because of performance
|
||||
[topbar/topbar {:navigation :none
|
||||
:left-component [react/view {:flex-direction :row :margin-left 16}
|
||||
[back-button]]
|
||||
:title-component [topbar-content]
|
||||
:right-component [react/view {:flex-direction :row :margin-right 16}
|
||||
[search-button]]
|
||||
:border-bottom false
|
||||
:new-ui? true}]
|
||||
[connectivity/loading-indicator]
|
||||
(when chat-id
|
||||
(if group-chat
|
||||
[invitation-requests chat-id admins]
|
||||
(when-not mutual-contact-requests-enabled? [add-contact-bar chat-id])))
|
||||
;;MESSAGES LIST
|
||||
[messages-view {:chat chat
|
||||
:bottom-space max-bottom-space
|
||||
:pan-responder pan-responder
|
||||
:mutual-contact-requests-enabled? mutual-contact-requests-enabled?
|
||||
:space-keeper space-keeper
|
||||
:show-input? show-input?}]
|
||||
(when (and group-chat invitation-admin)
|
||||
[accessory/view {:y position-y
|
||||
:on-update-inset on-update}
|
||||
[invitation-bar chat-id]])
|
||||
[components/autocomplete-mentions text-input-ref max-bottom-space]
|
||||
(when show-input?
|
||||
;; NOTE: this only accepts two children
|
||||
[accessory/view {:y position-y
|
||||
:pan-state pan-state
|
||||
:has-panel (boolean @active-panel)
|
||||
:on-close on-close
|
||||
:on-update-inset on-update}
|
||||
[react/view
|
||||
[edit/edit-message-auto-focus-wrapper text-input-ref]
|
||||
[reply/reply-message-auto-focus-wrapper text-input-ref]
|
||||
;; We set the key so we can force a re-render as
|
||||
;; it does not rely on ratom but just atoms
|
||||
^{:key (str @components/chat-input-key "chat-input")}
|
||||
[components/chat-toolbar
|
||||
{:chat-id chat-id
|
||||
:active-panel @active-panel
|
||||
:set-active-panel set-active-panel
|
||||
:text-input-ref text-input-ref}]
|
||||
[contact-request/contact-request-message-auto-focus-wrapper text-input-ref]]
|
||||
[bottom-sheet @active-panel]])]))))
|
||||
(let [{:keys [chat-id show-input? group-chat admins] :as chat}
|
||||
;;we want to react only on these fields, do not use full chat map here
|
||||
@(re-frame/subscribe [:chats/current-chat-chat-view])
|
||||
mutual-contact-requests-enabled? @(re-frame/subscribe [:mutual-contact-requests/enabled?])]
|
||||
[react/keyboard-avoiding-view-new {:style {:flex 1}
|
||||
:ignore-offset false}
|
||||
;; It is better to not use topbar component because of performance
|
||||
[topbar/topbar {:navigation :none
|
||||
:left-component [react/view {:flex-direction :row :margin-left 16}
|
||||
[back-button]]
|
||||
:title-component [topbar-content]
|
||||
:right-component [react/view {:flex-direction :row :margin-right 16}
|
||||
[search-button]]
|
||||
:border-bottom false
|
||||
:new-ui? true}]
|
||||
[connectivity/loading-indicator]
|
||||
(when chat-id
|
||||
(if group-chat
|
||||
[invitation-requests chat-id admins]
|
||||
(when-not mutual-contact-requests-enabled? [add-contact-bar chat-id])))
|
||||
;;MESSAGES LIST
|
||||
[messages-view {:chat chat
|
||||
:mutual-contact-requests-enabled? mutual-contact-requests-enabled?
|
||||
:show-input? show-input?}]
|
||||
;;INPUT COMPONENT
|
||||
(when show-input?
|
||||
[components/chat-input-bottom-sheet chat-id])]))
|
||||
|
||||
(defn chat-old []
|
||||
(reagent/create-class
|
||||
|
@ -676,8 +630,8 @@
|
|||
|
||||
(defn chat []
|
||||
(reagent/create-class
|
||||
{:component-did-mount (fn []
|
||||
(react/hw-back-remove-listener navigate-back-handler)
|
||||
(react/hw-back-add-listener navigate-back-handler))
|
||||
{:component-did-mount (fn []
|
||||
(react/hw-back-remove-listener navigate-back-handler)
|
||||
(react/hw-back-add-listener navigate-back-handler))
|
||||
:component-will-unmount (fn [] (react/hw-back-remove-listener navigate-back-handler))
|
||||
:reagent-render chat-render}))
|
||||
:reagent-render chat-render}))
|
||||
|
|
11
yarn.lock
11
yarn.lock
|
@ -6133,7 +6133,7 @@ lodash.union@^4.6.0:
|
|||
resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
|
||||
integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=
|
||||
|
||||
lodash@4.17.x:
|
||||
lodash@4.17.x, lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
@ -8026,14 +8026,15 @@ react-native-fs@^2.14.1:
|
|||
base-64 "^0.1.0"
|
||||
utf8 "^3.0.0"
|
||||
|
||||
react-native-gesture-handler@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.8.0.tgz#18f61f51da50320f938957b0ee79bc58f47449dc"
|
||||
integrity sha512-E2FZa0qZ5Bi0Z8Jg4n9DaFomHvedSjwbO2DPmUUHYRy1lH2yxXUpSrqJd6yymu+Efzmjg2+JZzsjFYA2Iq8VEQ==
|
||||
react-native-gesture-handler@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.5.0.tgz#61385583570ed0a45a9ed142425e35f8fe8274fb"
|
||||
integrity sha512-djZdcprFf08PZC332D+AeG5wcGeAPhzfCJtB3otUgOgTlvjVXmg/SLFdPJSpzLBqkRAmrC77tM79QgKbuLxkfw==
|
||||
dependencies:
|
||||
"@egjs/hammerjs" "^2.0.17"
|
||||
hoist-non-react-statics "^3.3.0"
|
||||
invariant "^2.2.4"
|
||||
lodash "^4.17.21"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-native-haptic-feedback@^1.9.0:
|
||||
|
|
Loading…
Reference in New Issue