parent
08fb0de7b0
commit
4e6a37fdd0
|
@ -34,7 +34,7 @@
|
||||||
(def touchable-opacity (reagent/adapt-react-class (.-TouchableOpacity ^js rn)))
|
(def touchable-opacity (reagent/adapt-react-class (.-TouchableOpacity ^js rn)))
|
||||||
(def touchable-highlight (reagent/adapt-react-class (.-TouchableHighlight ^js rn)))
|
(def touchable-highlight (reagent/adapt-react-class (.-TouchableHighlight ^js rn)))
|
||||||
(def touchable-without-feedback (reagent/adapt-react-class (.-TouchableWithoutFeedback ^js rn)))
|
(def touchable-without-feedback (reagent/adapt-react-class (.-TouchableWithoutFeedback ^js rn)))
|
||||||
(def text-input (reagent/adapt-react-class (.-TextInput ^js rn)))
|
(def text-input (reagent/adapt-react-class (.-TextInput ^js rn)))
|
||||||
|
|
||||||
(def keyboard-avoiding-view-class (reagent/adapt-react-class (.-KeyboardAvoidingView ^js rn)))
|
(def keyboard-avoiding-view-class (reagent/adapt-react-class (.-KeyboardAvoidingView ^js rn)))
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,10 @@
|
||||||
cursor (+ at-sign-idx (count name) 2)]
|
cursor (+ at-sign-idx (count name) 2)]
|
||||||
(fx/merge
|
(fx/merge
|
||||||
cofx
|
cofx
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
(assoc-in [:chats/cursor chat-id] cursor)
|
(assoc-in [:chats/cursor chat-id] cursor)
|
||||||
(assoc-in [:chats/mention-suggestions chat-id] nil))}
|
(assoc-in [:chats/mention-suggestions chat-id] nil))
|
||||||
|
:set-text-input-value [chat-id new-text text-input-ref]}
|
||||||
(set-chat-input-text new-text chat-id)
|
(set-chat-input-text new-text chat-id)
|
||||||
;; NOTE(rasom): Some keyboards do not react on selection property passed to
|
;; NOTE(rasom): Some keyboards do not react on selection property passed to
|
||||||
;; text input (specifically Samsung keyboard with predictive text set on).
|
;; text input (specifically Samsung keyboard with predictive text set on).
|
||||||
|
@ -126,7 +127,6 @@
|
||||||
|
|
||||||
text (get-in message [:content :text])]
|
text (get-in message [:content :text])]
|
||||||
{:dispatch [:chat.ui.input/set-chat-input-text text current-chat-id]
|
{:dispatch [:chat.ui.input/set-chat-input-text text current-chat-id]
|
||||||
:set-input-text [current-chat-id text]
|
|
||||||
:db (-> db
|
:db (-> db
|
||||||
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message]
|
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message]
|
||||||
message)
|
message)
|
||||||
|
@ -196,7 +196,7 @@
|
||||||
[{:keys [db] :as cofx}]
|
[{:keys [db] :as cofx}]
|
||||||
(let [current-chat-id (:current-chat-id db)]
|
(let [current-chat-id (:current-chat-id db)]
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:set-input-text [current-chat-id ""]}
|
{:set-text-input-value [current-chat-id ""]}
|
||||||
(clean-input current-chat-id)
|
(clean-input current-chat-id)
|
||||||
(mentions/clear-mentions)
|
(mentions/clear-mentions)
|
||||||
(mentions/clear-cursor))))
|
(mentions/clear-cursor))))
|
||||||
|
|
|
@ -208,7 +208,7 @@
|
||||||
e)) text-with-mentions)
|
e)) text-with-mentions)
|
||||||
info (mentions/->info hydrated-mentions)
|
info (mentions/->info hydrated-mentions)
|
||||||
new-text (string/join (map second hydrated-mentions))]
|
new-text (string/join (map second hydrated-mentions))]
|
||||||
{:set-input-text [chat-id new-text]
|
{:set-text-input-value [chat-id new-text]
|
||||||
:db
|
:db
|
||||||
(-> db
|
(-> db
|
||||||
(assoc-in [:chats/cursor chat-id] (:mention-end info))
|
(assoc-in [:chats/cursor chat-id] (:mention-end info))
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
[quo2.core :as quo]
|
[quo2.core :as quo]
|
||||||
[quo.gesture-handler :as gesture-handler]))
|
[quo.gesture-handler :as gesture-handler]))
|
||||||
|
|
||||||
(defn edit-message []
|
(defn edit-message [reset-composer-callback]
|
||||||
[rn/view {:style style/container
|
[rn/view {:style style/container
|
||||||
:accessibility-label :edit-message}
|
:accessibility-label :edit-message}
|
||||||
[rn/view {:style style/content-container}
|
[rn/view {:style style/content-container}
|
||||||
|
@ -20,7 +20,8 @@
|
||||||
(i18n/label :t/editing-message)]]]
|
(i18n/label :t/editing-message)]]]
|
||||||
[gesture-handler/touchable-without-feedback
|
[gesture-handler/touchable-without-feedback
|
||||||
{:accessibility-label :reply-cancel-button
|
{:accessibility-label :reply-cancel-button
|
||||||
:on-press #(rf/dispatch [:chat.ui/cancel-message-edit])}
|
:on-press #(do (reset-composer-callback true)
|
||||||
|
(rf/dispatch [:chat.ui/cancel-message-edit]))}
|
||||||
[quo/button {:width 24
|
[quo/button {:width 24
|
||||||
:size 24
|
:size 24
|
||||||
:type :outline}
|
:type :outline}
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
(defn edit-message-auto-focus-wrapper [text-input-ref _]
|
(defn edit-message-auto-focus-wrapper [text-input-ref _]
|
||||||
(let [had-edit (atom nil)]
|
(let [had-edit (atom nil)]
|
||||||
(fn [_ edit]
|
(fn [_ edit cleanup-composer-callback]
|
||||||
(focus-input-on-edit edit had-edit text-input-ref)
|
(focus-input-on-edit edit had-edit text-input-ref)
|
||||||
(when edit
|
(when edit
|
||||||
[rn/view {:style style/container}
|
[rn/view {:style style/container}
|
||||||
[edit/edit-message]]))))
|
[edit/edit-message cleanup-composer-callback]]))))
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
[oops.core :as oops]))
|
[oops.core :as oops]))
|
||||||
|
|
||||||
(defonce input-texts (atom {}))
|
(defonce input-texts (atom {}))
|
||||||
(defonce mentions-enabled (reagent/atom {}))
|
(defonce mentions-enabled? (reagent/atom {}))
|
||||||
(defonce chat-input-key (reagent/atom 1))
|
(defonce chat-input-key (reagent/atom 1))
|
||||||
(defonce text-input-ref (reagent/atom nil))
|
(defonce text-input-ref (reagent/atom nil))
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
:chat.ui/clear-inputs
|
:chat.ui/clear-inputs
|
||||||
(fn []
|
(fn []
|
||||||
(reset! input-texts {})
|
(reset! input-texts {})
|
||||||
(reset! mentions-enabled {})
|
(reset! mentions-enabled? {})
|
||||||
(reset! chat-input-key 1)))
|
(reset! chat-input-key 1)))
|
||||||
|
|
||||||
(defn input-focus [text-input-ref]
|
(defn input-focus [text-input-ref]
|
||||||
|
@ -51,14 +51,14 @@
|
||||||
|
|
||||||
(defn reset-input [refs chat-id]
|
(defn reset-input [refs chat-id]
|
||||||
(some-> ^js (quo.react/current-ref (:text-input-ref refs)) .clear)
|
(some-> ^js (quo.react/current-ref (:text-input-ref refs)) .clear)
|
||||||
(swap! mentions-enabled update :render not)
|
(swap! mentions-enabled? update :render not)
|
||||||
(swap! input-texts dissoc chat-id))
|
(swap! input-texts dissoc chat-id))
|
||||||
|
|
||||||
(defn clear-input [chat-id refs]
|
(defn clear-input [chat-id refs]
|
||||||
(hide-send refs)
|
(hide-send refs)
|
||||||
(if (get @mentions-enabled chat-id)
|
(if (get @mentions-enabled? chat-id)
|
||||||
(do
|
(do
|
||||||
(swap! mentions-enabled dissoc chat-id)
|
(swap! mentions-enabled? dissoc chat-id)
|
||||||
;;we need this timeout, because if we clear text input and first index was a mention object with blue color,
|
;;we need this timeout, because if we clear text input and first index was a mention object with blue color,
|
||||||
;;after clearing text will be typed with this blue color, so we render white text first and then clear it
|
;;after clearing text will be typed with this blue color, so we render white text first and then clear it
|
||||||
(js/setTimeout #(reset-input refs chat-id) 50))
|
(js/setTimeout #(reset-input refs chat-id) 50))
|
||||||
|
@ -105,8 +105,8 @@
|
||||||
(when (and (empty? prev-text) (seq text))
|
(when (and (empty? prev-text) (seq text))
|
||||||
(show-send refs))
|
(show-send refs))
|
||||||
|
|
||||||
(when (and (not (get @mentions-enabled chat-id)) (string/index-of text "@"))
|
(when (and (not (get @mentions-enabled? chat-id)) (string/index-of text "@"))
|
||||||
(swap! mentions-enabled assoc chat-id true))
|
(swap! mentions-enabled? assoc chat-id true))
|
||||||
|
|
||||||
;; NOTE(rasom): on iOS `on-selection-change` is canceled in case if it
|
;; NOTE(rasom): on iOS `on-selection-change` is canceled in case if it
|
||||||
;; happens during typing because it is not needed for mention
|
;; happens during typing because it is not needed for mention
|
||||||
|
@ -129,8 +129,8 @@
|
||||||
range (.-range ^js native-event)
|
range (.-range ^js native-event)
|
||||||
start (.-start ^js range)
|
start (.-start ^js range)
|
||||||
end (.-end ^js range)]
|
end (.-end ^js range)]
|
||||||
(when (and (not (get @mentions-enabled chat-id)) (string/index-of text "@"))
|
(when (and (not (get @mentions-enabled? chat-id)) (string/index-of text "@"))
|
||||||
(swap! mentions-enabled assoc chat-id true))
|
(swap! mentions-enabled? assoc chat-id true))
|
||||||
|
|
||||||
(>evt
|
(>evt
|
||||||
[::mentions/on-text-input
|
[::mentions/on-text-input
|
||||||
|
@ -144,38 +144,40 @@
|
||||||
(when platform/android?
|
(when platform/android?
|
||||||
(>evt [::mentions/calculate-suggestions mentionable-users]))))
|
(>evt [::mentions/calculate-suggestions mentionable-users]))))
|
||||||
|
|
||||||
(defn text-input [{:keys [set-active-panel refs chat-id sending-image on-content-size-change]}]
|
(defn text-input [{:keys [set-active-panel refs chat-id sending-image on-content-size-change initial-value]}]
|
||||||
(let [cooldown-enabled? (<sub [:chats/current-chat-cooldown-enabled?])
|
(let [_ (reset! text-input-ref (:text-input-ref refs))
|
||||||
mentionable-users (<sub [:chats/mentionable-users])
|
cooldown-enabled? (<sub [:chats/current-chat-cooldown-enabled?])
|
||||||
timeout-id (atom nil)
|
mentionable-users (<sub [:chats/mentionable-users])
|
||||||
last-text-change (atom nil)
|
timeout-id (reagent/atom nil)
|
||||||
mentions-enabled (get @mentions-enabled chat-id)
|
last-text-change (reagent/atom nil)
|
||||||
props {:style (style/text-input)
|
mentions-enabled? (get @mentions-enabled? chat-id)
|
||||||
:ref (:text-input-ref refs)
|
props {:style (style/text-input)
|
||||||
:max-font-size-multiplier 1
|
:ref (:text-input-ref refs)
|
||||||
:accessibility-label :chat-message-input
|
:max-font-size-multiplier 1
|
||||||
:text-align-vertical :center
|
:accessibility-label :chat-message-input
|
||||||
:multiline true
|
:text-align-vertical :center
|
||||||
:editable (not cooldown-enabled?)
|
:multiline true
|
||||||
:blur-on-submit false
|
:editable (not cooldown-enabled?)
|
||||||
:auto-focus false
|
:blur-on-submit false
|
||||||
:on-focus #(set-active-panel nil)
|
:auto-focus false
|
||||||
:max-length chat.constants/max-text-size
|
:default-value initial-value
|
||||||
:placeholder-text-color (:text-02 @quo.colors/theme)
|
:on-focus #(set-active-panel nil)
|
||||||
:placeholder (if cooldown-enabled?
|
:max-length chat.constants/max-text-size
|
||||||
(i18n/label :cooldown/text-input-disabled)
|
:placeholder-text-color (:text-02 @quo.colors/theme)
|
||||||
(i18n/label :t/type-a-message))
|
:placeholder (if cooldown-enabled?
|
||||||
:underline-color-android :transparent
|
(i18n/label :cooldown/text-input-disabled)
|
||||||
:auto-capitalize :sentences
|
(i18n/label :t/type-a-message))
|
||||||
:auto-correct false
|
:underline-color-android :transparent
|
||||||
:spell-check false
|
:auto-capitalize :sentences
|
||||||
:on-content-size-change on-content-size-change
|
:auto-correct false
|
||||||
:on-selection-change (partial on-selection-change timeout-id last-text-change mentionable-users)
|
:spell-check false
|
||||||
:on-change (partial on-change last-text-change timeout-id mentionable-users refs chat-id sending-image)
|
:on-content-size-change on-content-size-change
|
||||||
:on-text-input (partial on-text-input mentionable-users chat-id)}
|
: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)}
|
||||||
input-with-mentions (<sub [:chat/input-with-mentions])
|
input-with-mentions (<sub [:chat/input-with-mentions])
|
||||||
children (fn []
|
children (fn []
|
||||||
(if mentions-enabled
|
(if mentions-enabled?
|
||||||
(map-indexed
|
(map-indexed
|
||||||
(fn [index [item text]]
|
(fn [index [item text]]
|
||||||
[index [item]]
|
[index [item]]
|
||||||
|
@ -203,8 +205,10 @@
|
||||||
(.setNativeProps ^js text-input (clj->js {:text text})))
|
(.setNativeProps ^js text-input (clj->js {:text text})))
|
||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
:set-input-text
|
:set-text-input-value
|
||||||
(fn [[chat-id text]]
|
(fn [[chat-id text local-text-input-ref]]
|
||||||
|
(when local-text-input-ref
|
||||||
|
(reset! text-input-ref local-text-input-ref))
|
||||||
(if platform/ios?
|
(if platform/ios?
|
||||||
(.setNativeProps ^js (quo.react/current-ref @text-input-ref) (clj->js {:text text}))
|
(.setNativeProps ^js (quo.react/current-ref @text-input-ref) (clj->js {:text text}))
|
||||||
(do
|
(do
|
||||||
|
@ -297,7 +301,7 @@
|
||||||
(let [text-input-handle (rn/find-node-handle @text-input-ref)]
|
(let [text-input-handle (rn/find-node-handle @text-input-ref)]
|
||||||
(oops/ocall manager :startActionMode text-input-handle))))
|
(oops/ocall manager :startActionMode text-input-handle))))
|
||||||
|
|
||||||
:render
|
:reagent-render
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [ref #(do (reset! text-input-ref %)
|
(let [ref #(do (reset! text-input-ref %)
|
||||||
(when ref
|
(when ref
|
||||||
|
@ -333,9 +337,9 @@
|
||||||
:chat-id chat-id
|
:chat-id chat-id
|
||||||
:selection-event selection-event})))
|
:selection-event selection-event})))
|
||||||
props (merge props {:ref ref
|
props (merge props {:ref ref
|
||||||
:style nil
|
:style (dissoc style :margin-horizontal)
|
||||||
:on-selection-change on-selection-change
|
:on-selection-change on-selection-change
|
||||||
:on-selection on-selection})]
|
:on-selection on-selection})]
|
||||||
[rn-selectable-text-input {:menuItems @menu-items :style style}
|
[rn-selectable-text-input {:menuItems @menu-items :style style}
|
||||||
[rn/text-input props
|
[rn/text-input props
|
||||||
[children]]]))})))
|
children]]))})))
|
||||||
|
|
|
@ -40,17 +40,18 @@
|
||||||
ens-name?
|
ens-name?
|
||||||
(assoc :subtitle alias))]]))
|
(assoc :subtitle alias))]]))
|
||||||
|
|
||||||
(defn autocomplete-mentions [suggestions]
|
(defn autocomplete-mentions [suggestions text-input-ref]
|
||||||
[:f>
|
[:f>
|
||||||
(fn []
|
(fn []
|
||||||
(let [animation (reanimated/use-shared-value 0)]
|
(let [animation (reanimated/use-shared-value 0)]
|
||||||
(quo.react/effect! #(reanimated/set-shared-value animation (reanimated/with-timing (if (seq suggestions) 0 200))))
|
(quo.react/effect! #(reanimated/set-shared-value animation (reanimated/with-timing (if (seq suggestions) 0 200))))
|
||||||
[reanimated/view {:style (reanimated/apply-animations-to-style
|
[reanimated/view {:style (reanimated/apply-animations-to-style
|
||||||
{:transform [{:translateY animation}]}
|
{:transform [{:translateY animation}]}
|
||||||
{:bottom 0 :position :absolute :z-index 5 :max-height 180})}
|
{:bottom 0 :position :absolute :z-index 5 :elevation 5 :max-height 180})}
|
||||||
[list/flat-list
|
[list/flat-list
|
||||||
{:keyboardShouldPersistTaps :always
|
{:keyboardShouldPersistTaps :always
|
||||||
:data suggestions
|
:data suggestions
|
||||||
:key-fn first
|
:key-fn first
|
||||||
:render-fn mention-item
|
:render-fn mention-item
|
||||||
|
:render-data text-input-ref
|
||||||
:content-container-style {:padding-bottom 12}}]]))])
|
:content-container-style {:padding-bottom 12}}]]))])
|
||||||
|
|
|
@ -19,33 +19,42 @@
|
||||||
[i18n.i18n :as i18n]
|
[i18n.i18n :as i18n]
|
||||||
[status-im.ui2.screens.chat.composer.edit.view :as edit]))
|
[status-im.ui2.screens.chat.composer.edit.view :as edit]))
|
||||||
|
|
||||||
(defn calculate-y [context keyboard-shown min-y max-y added-value]
|
(defn calculate-y [context min-y max-y added-value chat-id]
|
||||||
(if keyboard-shown
|
(let [input-text (:input-text (get (<sub [:chat/inputs]) chat-id))
|
||||||
|
num-lines (count (string/split input-text "\n"))]
|
||||||
(if (= (:state @context) :max)
|
(if (= (:state @context) :max)
|
||||||
max-y
|
(do (swap! context assoc :state :max) max-y)
|
||||||
(if (< (:y @context) max-y)
|
(if (< (:y @context) max-y)
|
||||||
(+ (:y @context) added-value)
|
(+ (:y @context) added-value)
|
||||||
(do
|
(if (<= 5 num-lines)
|
||||||
(swap! context assoc :state :max)
|
(do (swap! context assoc :state :max) max-y)
|
||||||
max-y)))
|
(do (swap! context assoc :state :min) min-y))))))
|
||||||
(do
|
|
||||||
(swap! context assoc :state :min)
|
|
||||||
min-y)))
|
|
||||||
|
|
||||||
(defn calculate-y-with-mentions [y max-y max-height chat-id suggestions reply]
|
(defn calculate-y-with-mentions [y max-y max-height chat-id suggestions reply]
|
||||||
(let [input-text (:input-text (get (<sub [:chat/inputs]) chat-id))
|
(let [input-text (:input-text (get (<sub [:chat/inputs]) chat-id))
|
||||||
num-lines (count (string/split input-text "\n"))
|
num-lines (count (string/split input-text "\n"))
|
||||||
text-height (* num-lines 22)
|
text-height (* num-lines 22)
|
||||||
mentions-height (min 132 (+ 16 (* 46 (- (count suggestions) 1))))
|
mentions-height (min 132 (+ 16 (* 46 (- (count suggestions) 1))))
|
||||||
should-translate (if (< (- max-height text-height) mentions-height) true false)
|
should-translate? (if (< (- max-height text-height) mentions-height) true false)
|
||||||
min-value (if-not reply mentions-height (+ mentions-height 44))
|
min-value (if-not reply mentions-height (+ mentions-height 44))
|
||||||
; translate value when mentions list appear while at bottom of expanded input sheet
|
; translate value when mentions list appear while at bottom of expanded input sheet
|
||||||
mentions-translate-value (if should-translate (min min-value (- mentions-height (- max-height text-height))) mentions-height)]
|
mentions-translate-value (if should-translate? (min min-value (- mentions-height (- max-height text-height))) mentions-height)]
|
||||||
(when (or (< y max-y) should-translate) mentions-translate-value)))
|
(when (or (< y max-y) should-translate?) mentions-translate-value)))
|
||||||
|
|
||||||
(defn get-y-value [context keyboard-shown min-y max-y added-value max-height chat-id suggestions reply]
|
(defn get-y-value [context min-y max-y added-value max-height chat-id suggestions reply]
|
||||||
(let [y (calculate-y context keyboard-shown min-y max-y added-value)]
|
(let [y (calculate-y context min-y max-y added-value chat-id)
|
||||||
y (+ y (when (seq suggestions) (calculate-y-with-mentions y max-y max-height chat-id suggestions reply)))))
|
y-with-mentions (calculate-y-with-mentions y max-y max-height chat-id suggestions reply)]
|
||||||
|
(+ y (when (seq suggestions) y-with-mentions))))
|
||||||
|
|
||||||
|
(defn- clean-and-minimize-composer
|
||||||
|
([context chat-id refs min-y]
|
||||||
|
(clean-and-minimize-composer context chat-id refs min-y false))
|
||||||
|
([context chat-id refs min-y edit?]
|
||||||
|
(input/clear-input chat-id refs)
|
||||||
|
(swap! context assoc :y (if edit?
|
||||||
|
(- min-y 38)
|
||||||
|
min-y))
|
||||||
|
(swap! context assoc :clear true)))
|
||||||
|
|
||||||
(defn get-bottom-sheet-gesture [context translate-y text-input-ref keyboard-shown min-y max-y shared-height max-height set-bg-opacity]
|
(defn get-bottom-sheet-gesture [context translate-y text-input-ref keyboard-shown min-y max-y shared-height max-height set-bg-opacity]
|
||||||
(-> (gesture/gesture-pan)
|
(-> (gesture/gesture-pan)
|
||||||
|
@ -73,7 +82,6 @@
|
||||||
(reanimated/set-shared-value shared-height (reanimated/with-timing max-height))
|
(reanimated/set-shared-value shared-height (reanimated/with-timing max-height))
|
||||||
(set-bg-opacity 1))
|
(set-bg-opacity 1))
|
||||||
(do
|
(do
|
||||||
(swap! context assoc :state :min)
|
|
||||||
(reanimated/set-shared-value translate-y (reanimated/with-timing (- 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 shared-height (reanimated/with-timing min-y))
|
||||||
(set-bg-opacity 0)
|
(set-bg-opacity 0)
|
||||||
|
@ -90,7 +98,7 @@
|
||||||
(reanimated/set-shared-value shared-height (reanimated/with-timing min-y))
|
(reanimated/set-shared-value shared-height (reanimated/with-timing min-y))
|
||||||
(set-bg-opacity 0))
|
(set-bg-opacity 0))
|
||||||
(when (not= (:state @context) :max)
|
(when (not= (:state @context) :max)
|
||||||
(let [new-y (+ min-y (- (max (oget evt "nativeEvent" "contentSize" "height") 22) 22))]
|
(let [new-y (+ min-y (- (max (oget evt "nativeEvent" "contentSize" "height") 40) 40))]
|
||||||
(if (< new-y max-y)
|
(if (< new-y max-y)
|
||||||
(do
|
(do
|
||||||
(if (> (- max-y new-y) 120)
|
(if (> (- max-y new-y) 120)
|
||||||
|
@ -120,58 +128,56 @@
|
||||||
(defn composer [chat-id]
|
(defn composer [chat-id]
|
||||||
[safe-area/consumer
|
[safe-area/consumer
|
||||||
(fn [insets]
|
(fn [insets]
|
||||||
(let [min-y 112
|
(let [min-y 112
|
||||||
context (atom {:y min-y ;current y value
|
context (atom {:y min-y ;current y value
|
||||||
:min-y min-y ;minimum y value
|
:min-y min-y ;minimum y value
|
||||||
:dy 0 ;used for gesture
|
:dy 0 ;used for gesture
|
||||||
:pdy 0 ;used for gesture
|
:pdy 0 ;used for gesture
|
||||||
:state :min ;:min, :custom-chat-available, :custom-chat-unavailable, :max
|
:state :min ;:min, :custom-chat-available, :custom-chat-unavailable, :max
|
||||||
:clear false})
|
:clear false})
|
||||||
keyboard-was-shown (atom false)
|
keyboard-was-shown? (atom false)
|
||||||
text-input-ref (quo.react/create-ref)
|
text-input-ref (quo.react/create-ref)
|
||||||
send-ref (quo.react/create-ref)
|
send-ref (quo.react/create-ref)
|
||||||
refs {:send-ref send-ref
|
refs {:send-ref send-ref
|
||||||
:text-input-ref text-input-ref}]
|
:text-input-ref text-input-ref}]
|
||||||
(fn []
|
(fn []
|
||||||
[:f>
|
[:f>
|
||||||
(fn []
|
(fn []
|
||||||
(let [reply (<sub [:chats/reply-message])
|
(let [reply (<sub [:chats/reply-message])
|
||||||
edit (<sub [:chats/edit-message])
|
edit (<sub [:chats/edit-message])
|
||||||
suggestions (<sub [:chat/mention-suggestions])
|
suggestions (<sub [:chat/mention-suggestions])
|
||||||
{window-height :height} (rn/use-window-dimensions)
|
{window-height :height} (rn/use-window-dimensions)
|
||||||
{:keys [keyboard-shown keyboard-height]} (rn/use-keyboard)
|
{:keys [keyboard-shown keyboard-height]} (rn/use-keyboard)
|
||||||
max-y (- window-height (if (> keyboard-height 0) keyboard-height 360) (:top insets) (:status-bar-height @navigation-const)) ; 360 - default height
|
max-y (- window-height (if (> keyboard-height 0) keyboard-height 360) (:top insets) (:status-bar-height @navigation-const)) ; 360 - default height
|
||||||
max-height (Math/abs (- max-y 56 (:bottom insets))) ; 56 - top-bar height
|
max-height (Math/abs (- max-y 56 (:bottom insets))) ; 56 - top-bar height
|
||||||
added-value (if (and (not (seq suggestions)) (or edit reply)) 38 0) ; increased height of input box needed when reply
|
added-value (if (and (not (seq suggestions)) (or edit reply)) 38 0) ; increased height of input box needed when reply
|
||||||
min-y (+ min-y (when (or edit reply) 38))
|
min-y (+ min-y (when (or edit reply) 38))
|
||||||
y (get-y-value context keyboard-shown min-y max-y added-value max-height chat-id suggestions reply)
|
y (get-y-value context min-y max-y added-value max-height chat-id suggestions reply)
|
||||||
translate-y (reanimated/use-shared-value 0)
|
translate-y (reanimated/use-shared-value 0)
|
||||||
shared-height (reanimated/use-shared-value min-y)
|
shared-height (reanimated/use-shared-value min-y)
|
||||||
bg-opacity (reanimated/use-shared-value 0)
|
bg-opacity (reanimated/use-shared-value 0)
|
||||||
bg-bottom (reanimated/use-shared-value (- window-height))
|
clean-and-minimize-composer-fn #(clean-and-minimize-composer context chat-id refs min-y %)
|
||||||
|
bg-bottom (reanimated/use-shared-value (- window-height))
|
||||||
set-bg-opacity (fn [value]
|
set-bg-opacity (fn [value]
|
||||||
(reanimated/set-shared-value bg-bottom (if (= value 1) 0 (- window-height)))
|
(reanimated/set-shared-value bg-bottom (if (= value 1) 0 (- window-height)))
|
||||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing value)))
|
(reanimated/set-shared-value bg-opacity (reanimated/with-timing value)))
|
||||||
input-content-change (get-input-content-change context translate-y shared-height max-height
|
input-content-change (get-input-content-change context translate-y shared-height max-height
|
||||||
set-bg-opacity keyboard-shown min-y max-y)
|
set-bg-opacity keyboard-shown min-y max-y)
|
||||||
bottom-sheet-gesture (get-bottom-sheet-gesture context translate-y (:text-input-ref refs) keyboard-shown
|
blank-composer? (string/blank? (get @input/input-texts chat-id))
|
||||||
min-y max-y shared-height max-height set-bg-opacity)]
|
bottom-sheet-gesture (get-bottom-sheet-gesture context translate-y text-input-ref keyboard-shown
|
||||||
|
min-y max-y shared-height max-height set-bg-opacity)
|
||||||
|
initial-value (or (get @input/input-texts chat-id) nil)]
|
||||||
(quo.react/effect! #(do
|
(quo.react/effect! #(do
|
||||||
(when (and @keyboard-was-shown (not keyboard-shown))
|
(when (and @keyboard-was-shown? (not keyboard-shown))
|
||||||
(swap! context assoc :state :min))
|
(swap! context assoc :state :min))
|
||||||
(reset! keyboard-was-shown keyboard-shown)
|
(when blank-composer?
|
||||||
|
(clean-and-minimize-composer-fn false))
|
||||||
|
(reset! keyboard-was-shown? keyboard-shown)
|
||||||
(if (#{:max :custom-chat-unavailable} (:state @context))
|
(if (#{:max :custom-chat-unavailable} (:state @context))
|
||||||
(set-bg-opacity 1)
|
(set-bg-opacity 1)
|
||||||
(set-bg-opacity 0))
|
(set-bg-opacity 0))
|
||||||
(reanimated/set-shared-value translate-y (reanimated/with-timing (- y)))
|
(reanimated/set-shared-value translate-y (reanimated/with-timing (- y)))
|
||||||
(reanimated/set-shared-value shared-height (reanimated/with-timing (min y max-height)))))
|
(reanimated/set-shared-value shared-height (reanimated/with-timing (min y max-height)))))
|
||||||
(quo.react/effect! #(when (and (not edit) (= (:state @context) :max))
|
|
||||||
(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))
|
|
||||||
(set-bg-opacity 0)
|
|
||||||
(re-frame/dispatch [:dismiss-keyboard])) edit)
|
|
||||||
[reanimated/view {:style (reanimated/apply-animations-to-style
|
[reanimated/view {:style (reanimated/apply-animations-to-style
|
||||||
{:height shared-height}
|
{:height shared-height}
|
||||||
{:z-index 2})}
|
{:z-index 2})}
|
||||||
|
@ -182,12 +188,13 @@
|
||||||
(styles/input-bottom-sheet window-height))}
|
(styles/input-bottom-sheet window-height))}
|
||||||
;handle
|
;handle
|
||||||
[rn/view {:style (styles/bottom-sheet-handle)}]
|
[rn/view {:style (styles/bottom-sheet-handle)}]
|
||||||
[edit/edit-message-auto-focus-wrapper (:text-input-ref refs) edit]
|
[edit/edit-message-auto-focus-wrapper text-input-ref edit clean-and-minimize-composer-fn]
|
||||||
[reply/reply-message-auto-focus-wrapper (:text-input-ref refs) reply]
|
[reply/reply-message-auto-focus-wrapper text-input-ref reply]
|
||||||
[rn/view {:style {:height (- max-y 80 added-value)}}
|
[rn/view {:style {:height (- max-y 80 added-value)}}
|
||||||
[input/text-input {:chat-id chat-id
|
[input/text-input {:chat-id chat-id
|
||||||
:on-content-size-change input-content-change
|
:on-content-size-change input-content-change
|
||||||
:sending-image false
|
:sending-image false
|
||||||
|
:initial-value initial-value
|
||||||
:refs refs
|
:refs refs
|
||||||
:set-active-panel #()}]]]]
|
:set-active-panel #()}]]]]
|
||||||
;CONTROLS
|
;CONTROLS
|
||||||
|
@ -202,20 +209,27 @@
|
||||||
(utils/set-timeout
|
(utils/set-timeout
|
||||||
#(utils/show-popup (i18n/label :t/error)
|
#(utils/show-popup (i18n/label :t/error)
|
||||||
(i18n/label :t/external-storage-denied)) 50))}))
|
(i18n/label :t/external-storage-denied)) 50))}))
|
||||||
:icon true :type :outline :size 32} :i/image]
|
:icon true
|
||||||
|
:type :outline
|
||||||
|
:size 32} :i/image]
|
||||||
[rn/view {:width 12}]
|
[rn/view {:width 12}]
|
||||||
[quo2.button/button {:icon true :type :outline :size 32} :i/reaction]
|
[quo2.button/button {:icon true
|
||||||
|
:type :outline
|
||||||
|
:size 32} :i/reaction]
|
||||||
[rn/view {:flex 1}]
|
[rn/view {:flex 1}]
|
||||||
;;SEND button
|
;;SEND button
|
||||||
[rn/view {:ref send-ref :style (when-not (seq (get @input/input-texts chat-id)) {:width 0 :right -100})}
|
[rn/view {:ref send-ref
|
||||||
[quo2.button/button {:icon true :size 32 :accessibility-label :send-message-button
|
:style (when-not (seq (get @input/input-texts chat-id)) {:width 0
|
||||||
:on-press #(do (swap! context assoc :clear true)
|
:right -100})}
|
||||||
(input/clear-input chat-id refs)
|
[quo2.button/button {:icon true
|
||||||
(re-frame/dispatch [:chat.ui/send-current-message]))}
|
:size 32
|
||||||
|
:accessibility-label :send-message-button
|
||||||
|
:on-press #(do (clean-and-minimize-composer-fn false)
|
||||||
|
(re-frame/dispatch [:chat.ui/send-current-message]))}
|
||||||
:i/arrow-up]]])
|
:i/arrow-up]]])
|
||||||
;black background
|
;black background
|
||||||
[reanimated/view {:style (reanimated/apply-animations-to-style
|
[reanimated/view {:style (reanimated/apply-animations-to-style
|
||||||
{:opacity bg-opacity
|
{:opacity bg-opacity
|
||||||
:transform [{:translateY bg-bottom}]}
|
:transform [{:translateY bg-bottom}]}
|
||||||
(styles/bottom-sheet-background window-height))}]
|
(styles/bottom-sheet-background window-height))}]
|
||||||
[mentions/autocomplete-mentions suggestions]]))])))])
|
[mentions/autocomplete-mentions suggestions text-input-ref]]))])))])
|
||||||
|
|
Loading…
Reference in New Issue