[#10385] [perfromance][chat] Optimize input field in chat
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
parent
f280d5a90e
commit
f73754af34
|
@ -32,12 +32,12 @@
|
||||||
"keyboardDidShow"
|
"keyboardDidShow"
|
||||||
(fn [e]
|
(fn [e]
|
||||||
(let [h (.. e -endCoordinates -height)]
|
(let [h (.. e -endCoordinates -height)]
|
||||||
(dispatch [:set :keyboard-height h])
|
(dispatch-sync [:set :keyboard-height h])
|
||||||
(dispatch [:set :keyboard-max-height h]))))
|
(dispatch-sync [:set :keyboard-max-height h]))))
|
||||||
(.addListener react/keyboard
|
(.addListener react/keyboard
|
||||||
"keyboardDidHide"
|
"keyboardDidHide"
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(dispatch [:set :keyboard-height 0])))
|
(dispatch-sync [:set :keyboard-height 0])))
|
||||||
(.hide react/splash-screen)
|
(.hide react/splash-screen)
|
||||||
(.addEventListener react/app-state "change" app-state-change-handler)
|
(.addEventListener react/app-state "change" app-state-change-handler)
|
||||||
(.addEventListener rn-dependencies/react-native-languages "change" on-languages-change)
|
(.addEventListener rn-dependencies/react-native-languages "change" on-languages-change)
|
||||||
|
|
|
@ -308,3 +308,8 @@
|
||||||
(fx/merge (assoc-in cofx [:db :contacts/identity] identity)
|
(fx/merge (assoc-in cofx [:db :contacts/identity] identity)
|
||||||
(contact.core/create-contact identity)
|
(contact.core/create-contact identity)
|
||||||
(navigation/navigate-to-cofx :profile nil)))
|
(navigation/navigate-to-cofx :profile nil)))
|
||||||
|
|
||||||
|
(fx/defn input-on-focus
|
||||||
|
{:events [:chat.ui/input-on-focus]}
|
||||||
|
[{db :db}]
|
||||||
|
{:db (set-chat-ui-props db {:input-bottom-sheet nil})})
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
"Set input text for current-chat. Takes db and input text and cofx
|
"Set input text for current-chat. Takes db and input text and cofx
|
||||||
as arguments and returns new fx. Always clear all validation messages."
|
as arguments and returns new fx. Always clear all validation messages."
|
||||||
[{{:keys [current-chat-id] :as db} :db} new-input]
|
[{{:keys [current-chat-id] :as db} :db} new-input]
|
||||||
{:db (assoc-in db [:chats current-chat-id :input-text] (text->emoji new-input))})
|
{:db (assoc-in db [:chat/inputs current-chat-id :input-text] (text->emoji new-input))})
|
||||||
|
|
||||||
(defn- start-cooldown [{:keys [db]} cooldowns]
|
(defn- start-cooldown [{:keys [db]} cooldowns]
|
||||||
{:dispatch-later [{:dispatch [:chat/disable-cooldown]
|
{:dispatch-later [{:dispatch [:chat/disable-cooldown]
|
||||||
|
@ -67,6 +67,12 @@
|
||||||
(when-let [cmp-ref (get-in chat-ui-props [current-chat-id ref])]
|
(when-let [cmp-ref (get-in chat-ui-props [current-chat-id ref])]
|
||||||
{::focus-rn-component cmp-ref}))
|
{::focus-rn-component cmp-ref}))
|
||||||
|
|
||||||
|
(fx/defn chat-input-clear
|
||||||
|
"Returns fx for focusing on active chat input reference"
|
||||||
|
[{{:keys [current-chat-id chat-ui-props]} :db} ref]
|
||||||
|
(when-let [cmp-ref (get-in chat-ui-props [current-chat-id ref])]
|
||||||
|
{::clear-rn-component cmp-ref}))
|
||||||
|
|
||||||
(fx/defn reply-to-message
|
(fx/defn reply-to-message
|
||||||
"Sets reference to previous chat message and focuses on input"
|
"Sets reference to previous chat message and focuses on input"
|
||||||
[{:keys [db] :as cofx} message-id]
|
[{:keys [db] :as cofx} message-id]
|
||||||
|
@ -103,6 +109,7 @@
|
||||||
:response-to message-id
|
:response-to message-id
|
||||||
:ens-name preferred-name})
|
:ens-name preferred-name})
|
||||||
(set-chat-input-text nil)
|
(set-chat-input-text nil)
|
||||||
|
(chat-input-clear :input-ref)
|
||||||
(process-cooldown)))))
|
(process-cooldown)))))
|
||||||
|
|
||||||
(fx/defn send-sticker-fx
|
(fx/defn send-sticker-fx
|
||||||
|
@ -117,15 +124,15 @@
|
||||||
(fx/defn send-current-message
|
(fx/defn send-current-message
|
||||||
"Sends message from current chat input"
|
"Sends message from current chat input"
|
||||||
[{{:keys [current-chat-id] :as db} :db :as cofx}]
|
[{{:keys [current-chat-id] :as db} :db :as cofx}]
|
||||||
(let [{:keys [input-text]} (get-in db [:chats current-chat-id])]
|
(let [{:keys [input-text]} (get-in db [:chat/inputs current-chat-id])]
|
||||||
(plain-text-message-fx input-text current-chat-id cofx)))
|
(plain-text-message-fx input-text current-chat-id cofx)))
|
||||||
|
|
||||||
(fx/defn send-transaction-result
|
(fx/defn send-transaction-result
|
||||||
{:events [:chat/send-transaction-result]}
|
{:events [:chat/send-transaction-result]}
|
||||||
[cofx chat-id params result]
|
[cofx chat-id params result])
|
||||||
;;TODO: should be implemented on status-go side
|
;;TODO: should be implemented on status-go side
|
||||||
;;see https://github.com/status-im/team-core/blob/6c3d67d8e8bd8500abe52dab06a59e976ec942d2/rfc-001.md#status-gostatus-react-interface
|
;;see https://github.com/status-im/team-core/blob/6c3d67d8e8bd8500abe52dab06a59e976ec942d2/rfc-001.md#status-gostatus-react-interface
|
||||||
)
|
|
||||||
|
|
||||||
;; effects
|
;; effects
|
||||||
|
|
||||||
|
@ -136,3 +143,11 @@
|
||||||
(.focus ref)
|
(.focus ref)
|
||||||
(catch :default e
|
(catch :default e
|
||||||
(log/debug "Cannot focus the reference")))))
|
(log/debug "Cannot focus the reference")))))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
::clear-rn-component
|
||||||
|
(fn [ref]
|
||||||
|
(try
|
||||||
|
(.clear ref)
|
||||||
|
(catch :default e
|
||||||
|
(log/debug "Cannot clear the reference")))))
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
(s/def :chat/loaded-chats (s/nilable seq?))
|
(s/def :chat/loaded-chats (s/nilable seq?))
|
||||||
(s/def :chat/bot-db (s/nilable map?))
|
(s/def :chat/bot-db (s/nilable map?))
|
||||||
(s/def :chat/cooldowns (s/nilable number?)) ; number of cooldowns given for spamming send button
|
(s/def :chat/cooldowns (s/nilable number?)) ; number of cooldowns given for spamming send button
|
||||||
|
(s/def :chat/inputs (s/nilable map?))
|
||||||
(s/def :chat/cooldown-enabled? (s/nilable boolean?))
|
(s/def :chat/cooldown-enabled? (s/nilable boolean?))
|
||||||
(s/def :chat/last-outgoing-message-sent-at (s/nilable number?))
|
(s/def :chat/last-outgoing-message-sent-at (s/nilable number?))
|
||||||
(s/def :chat/spam-messages-frequency (s/nilable number?)) ; number of consecutive spam messages sent
|
(s/def :chat/spam-messages-frequency (s/nilable number?)) ; number of consecutive spam messages sent
|
||||||
|
|
|
@ -30,11 +30,11 @@
|
||||||
"keyboardWillShow"
|
"keyboardWillShow"
|
||||||
(fn [e]
|
(fn [e]
|
||||||
(let [h (.. e -endCoordinates -height)]
|
(let [h (.. e -endCoordinates -height)]
|
||||||
(dispatch [:set :keyboard-height h])
|
(dispatch-sync [:set :keyboard-height h])
|
||||||
(dispatch [:set :keyboard-max-height h]))))
|
(dispatch-sync [:set :keyboard-max-height h]))))
|
||||||
(.addListener react/keyboard
|
(.addListener react/keyboard
|
||||||
"keyboardWillHide"
|
"keyboardWillHide"
|
||||||
#(dispatch [:set :keyboard-height 0]))
|
#(dispatch-sync [:set :keyboard-height 0]))
|
||||||
(.hide react/splash-screen)
|
(.hide react/splash-screen)
|
||||||
(.addEventListener react/app-state "change" app-state-change-handler)
|
(.addEventListener react/app-state "change" app-state-change-handler)
|
||||||
(.addEventListener rn-dependencies/react-native-languages "change" on-languages-change)
|
(.addEventListener rn-dependencies/react-native-languages "change" on-languages-change)
|
||||||
|
|
|
@ -126,6 +126,7 @@
|
||||||
(reg-root-key-sub :group-chat-profile/editing? :group-chat-profile/editing?)
|
(reg-root-key-sub :group-chat-profile/editing? :group-chat-profile/editing?)
|
||||||
(reg-root-key-sub :group-chat-profile/profile :group-chat-profile/profile)
|
(reg-root-key-sub :group-chat-profile/profile :group-chat-profile/profile)
|
||||||
(reg-root-key-sub :selected-participants :selected-participants)
|
(reg-root-key-sub :selected-participants :selected-participants)
|
||||||
|
(reg-root-key-sub :chat/inputs :chat/inputs)
|
||||||
|
|
||||||
;;browser
|
;;browser
|
||||||
(reg-root-key-sub :browsers :browser/browsers)
|
(reg-root-key-sub :browsers :browser/browsers)
|
||||||
|
@ -607,25 +608,14 @@
|
||||||
:else 272)))
|
:else 272)))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:chats/input-margin
|
:chats/empty-chat-panel-height
|
||||||
:<- [:keyboard-height]
|
:<- [:keyboard-height]
|
||||||
:<- [:chats/current-chat-ui-prop :input-bottom-sheet]
|
(fn [kb-height]
|
||||||
(fn [[kb-height input-bottom-sheet]]
|
(if (and platform/ios? (pos? kb-height))
|
||||||
(cond
|
(- kb-height
|
||||||
;; During the transition of bottom sheet and close of keyboard happens
|
tabs.styles/minimized-tabs-height
|
||||||
;; The heights are summed up and input grows too much
|
(if platform/iphone-x? 34 0))
|
||||||
(not (nil? input-bottom-sheet))
|
0)))
|
||||||
0
|
|
||||||
|
|
||||||
(and platform/iphone-x? (> kb-height 0))
|
|
||||||
(- kb-height tabs.styles/minimized-tabs-height 34)
|
|
||||||
|
|
||||||
platform/ios?
|
|
||||||
(+ kb-height (- (if (> kb-height 0)
|
|
||||||
tabs.styles/minimized-tabs-height
|
|
||||||
0)))
|
|
||||||
|
|
||||||
:default 0)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:chats/active-chats
|
:chats/active-chats
|
||||||
|
@ -706,9 +696,10 @@
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:chats/current-chat-input-text
|
:chats/current-chat-input-text
|
||||||
:<- [:chats/current-raw-chat]
|
:<- [:chats/current-chat-id]
|
||||||
(fn [chat]
|
:<- [:chat/inputs]
|
||||||
(:input-text chat)))
|
(fn [[chat-id inputs]]
|
||||||
|
(get-in inputs [chat-id :input-text])))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:chats/current-chat
|
:chats/current-chat
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
(ns status-im.ui.screens.chat.input.input
|
(ns status-im.ui.screens.chat.input.input
|
||||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.ui.screens.chat.styles.input.input :as style]
|
[status-im.ui.screens.chat.styles.input.input :as style]
|
||||||
[status-im.ui.screens.chat.styles.message.message :as message-style]
|
[status-im.ui.screens.chat.styles.message.message :as message-style]
|
||||||
|
@ -12,103 +11,26 @@
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||||
[status-im.utils.platform :as platform]
|
|
||||||
[status-im.utils.config :as config]
|
[status-im.utils.config :as config]
|
||||||
[status-im.ui.screens.chat.stickers.views :as stickers]
|
[status-im.ui.screens.chat.stickers.views :as stickers]
|
||||||
[status-im.ui.screens.chat.extensions.views :as extensions]))
|
[status-im.ui.screens.chat.extensions.views :as extensions]))
|
||||||
|
|
||||||
(defview basic-text-input [{:keys [set-container-width-fn height single-line-input?]}]
|
(defn basic-text-input [input-text cooldown-enabled?]
|
||||||
(letsubs [input-text [:chats/current-chat-input-text]
|
[react/text-input
|
||||||
cooldown-enabled? [:chats/cooldown-enabled?]]
|
{:ref #(when % (re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-ref %}]))
|
||||||
[react/text-input
|
:accessibility-label :chat-message-input
|
||||||
(merge
|
:multiline true
|
||||||
{:ref #(when % (re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-ref %}]))
|
:default-value (or input-text "")
|
||||||
:accessibility-label :chat-message-input
|
:editable (not cooldown-enabled?)
|
||||||
:multiline (not single-line-input?)
|
:blur-on-submit false
|
||||||
:default-value (or input-text "")
|
:on-focus #(re-frame/dispatch-sync [:chat.ui/input-on-focus])
|
||||||
:editable (not cooldown-enabled?)
|
:on-change #(re-frame/dispatch [:chat.ui/set-chat-input-text (.-text (.-nativeEvent %))])
|
||||||
:blur-on-submit false
|
:style style/input-view
|
||||||
:on-focus #(re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-bottom-sheet nil}])
|
:placeholder (if cooldown-enabled?
|
||||||
:on-submit-editing #(when single-line-input?
|
(i18n/label :cooldown/text-input-disabled)
|
||||||
(re-frame/dispatch [:chat.ui/send-current-message]))
|
(i18n/label :t/type-a-message))
|
||||||
:on-layout #(set-container-width-fn (.-width (.-layout (.-nativeEvent %))))
|
:placeholder-text-color colors/gray
|
||||||
:on-change #(re-frame/dispatch [:chat.ui/set-chat-input-text (.-text (.-nativeEvent %))])
|
:auto-capitalize :sentences}])
|
||||||
:on-selection-change #(let [s (-> (.-nativeEvent %)
|
|
||||||
(.-selection))
|
|
||||||
end (.-end s)]
|
|
||||||
(re-frame/dispatch [:chat.ui/set-chat-ui-props {:selection end}]))
|
|
||||||
:style (style/input-view single-line-input?)
|
|
||||||
:placeholder-text-color colors/gray
|
|
||||||
:auto-capitalize :sentences}
|
|
||||||
(when cooldown-enabled?
|
|
||||||
{:placeholder (i18n/label :cooldown/text-input-disabled)}))]))
|
|
||||||
|
|
||||||
(defview basic-text-input-desktop [{:keys [set-container-width-fn height single-line-input? set-text state-text]}]
|
|
||||||
(letsubs [inp-ref (atom nil)
|
|
||||||
cooldown-enabled? [:chats/cooldown-enabled?]]
|
|
||||||
[react/text-input
|
|
||||||
(merge
|
|
||||||
{:ref #(when % (do
|
|
||||||
(reset! inp-ref %)
|
|
||||||
(re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-ref %}])))
|
|
||||||
:accessibility-label :chat-message-input
|
|
||||||
:multiline (not single-line-input?)
|
|
||||||
:default-value @state-text
|
|
||||||
:editable (not cooldown-enabled?)
|
|
||||||
:blur-on-submit false
|
|
||||||
:on-focus #(re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-bottom-sheet nil}])
|
|
||||||
:submit-shortcut {:key "Enter"}
|
|
||||||
:on-submit-editing #(do
|
|
||||||
(.clear @inp-ref)
|
|
||||||
(.focus @inp-ref)
|
|
||||||
(re-frame/dispatch [:chat.ui/set-chat-input-text @state-text])
|
|
||||||
(re-frame/dispatch [:chat.ui/send-current-message])
|
|
||||||
(set-text ""))
|
|
||||||
:on-layout #(set-container-width-fn (.-width (.-layout (.-nativeEvent %))))
|
|
||||||
:on-change #(do
|
|
||||||
(set-text (.-text (.-nativeEvent %))))
|
|
||||||
:on-end-editing #(re-frame/dispatch [:chat.ui/set-chat-input-text @state-text])
|
|
||||||
:on-selection-change #(let [s (-> (.-nativeEvent %)
|
|
||||||
(.-selection))
|
|
||||||
end (.-end s)]
|
|
||||||
(re-frame/dispatch [:chat.ui/set-chat-ui-props {:selection end}]))
|
|
||||||
:style (style/input-view single-line-input?)
|
|
||||||
:placeholder-text-color colors/gray
|
|
||||||
:auto-capitalize :sentences}
|
|
||||||
(when cooldown-enabled?
|
|
||||||
{:placeholder (i18n/label :cooldown/text-input-disabled)}))]))
|
|
||||||
|
|
||||||
(defview invisible-input [{:keys [set-layout-width-fn value]}]
|
|
||||||
(letsubs [input-text [:chats/current-chat-input-text]]
|
|
||||||
[react/text {:style style/invisible-input-text
|
|
||||||
:on-layout #(let [w (-> (.-nativeEvent %)
|
|
||||||
(.-layout)
|
|
||||||
(.-width))]
|
|
||||||
(set-layout-width-fn w))}
|
|
||||||
(or input-text "")]))
|
|
||||||
|
|
||||||
(defn get-options [type]
|
|
||||||
(case (keyword type)
|
|
||||||
:phone {:keyboard-type "phone-pad"}
|
|
||||||
:password {:secure-text-entry true}
|
|
||||||
:number {:keyboard-type "numeric"}
|
|
||||||
nil))
|
|
||||||
|
|
||||||
(defview input-view [{:keys [single-line-input? set-text state-text]}]
|
|
||||||
(let [component (reagent/current-component)
|
|
||||||
set-layout-width-fn #(reagent/set-state component {:width %})
|
|
||||||
set-container-width-fn #(reagent/set-state component {:container-width %})
|
|
||||||
{:keys [width]} (reagent/state component)]
|
|
||||||
[react/view {:style style/input-root}
|
|
||||||
[react/animated-view {:style style/input-animated}
|
|
||||||
[invisible-input {:set-layout-width-fn set-layout-width-fn}]
|
|
||||||
(if platform/desktop?
|
|
||||||
[basic-text-input-desktop {:set-container-width-fn set-container-width-fn
|
|
||||||
:single-line-input? single-line-input?
|
|
||||||
:set-text set-text
|
|
||||||
:state-text state-text}]
|
|
||||||
[basic-text-input {:set-container-width-fn set-container-width-fn
|
|
||||||
:single-line-input? single-line-input?}])]]))
|
|
||||||
|
|
||||||
(defview reply-message [from alias message-text]
|
(defview reply-message [from alias message-text]
|
||||||
(letsubs [{:keys [ens-name]} [:contacts/contact-name-by-identity from]
|
(letsubs [{:keys [ens-name]} [:contacts/contact-name-by-identity from]
|
||||||
|
@ -121,51 +43,34 @@
|
||||||
(defview reply-message-view []
|
(defview reply-message-view []
|
||||||
(letsubs [{:keys [content from alias] :as message} [:chats/reply-message]]
|
(letsubs [{:keys [content from alias] :as message} [:chats/reply-message]]
|
||||||
(when message
|
(when message
|
||||||
[react/view {:style style/reply-message-container}
|
[react/view {:style style/reply-message}
|
||||||
[react/view {:style style/reply-message}
|
[photos/member-photo from]
|
||||||
[photos/member-photo from]
|
[reply-message from alias (:text content)]
|
||||||
[reply-message from alias (:text content)]
|
[react/touchable-highlight
|
||||||
[react/touchable-highlight
|
{:style style/cancel-reply-highlight
|
||||||
{:style style/cancel-reply-highlight
|
:on-press #(re-frame/dispatch [:chat.ui/cancel-message-reply])
|
||||||
:on-press #(re-frame/dispatch [:chat.ui/cancel-message-reply])
|
:accessibility-label :cancel-message-reply}
|
||||||
:accessibility-label :cancel-message-reply}
|
[react/view {:style style/cancel-reply-container}
|
||||||
[react/view {:style style/cancel-reply-container}
|
[vector-icons/icon :main-icons/close {:container-style style/cancel-reply-icon
|
||||||
[vector-icons/icon :main-icons/close {:container-style style/cancel-reply-icon
|
:width 19
|
||||||
:width 19
|
:height 19
|
||||||
:height 19
|
:color colors/white}]]]])))
|
||||||
:color colors/white}]]]]])))
|
|
||||||
|
|
||||||
(defview container []
|
(defview container []
|
||||||
(letsubs [margin [:chats/input-margin]
|
(letsubs [mainnet? [:mainnet?]
|
||||||
mainnet? [:mainnet?]
|
input-text [:chats/current-chat-input-text]
|
||||||
input-text [:chats/current-chat-input-text]
|
cooldown-enabled? [:chats/cooldown-enabled?]
|
||||||
result-box [:chats/current-chat-ui-prop :result-box]
|
input-bottom-sheet [:chats/current-chat-ui-prop :input-bottom-sheet]
|
||||||
input-bottom-sheet [:chats/current-chat-ui-prop :input-bottom-sheet]
|
one-to-one-chat? [:current-chat/one-to-one-chat?]]
|
||||||
one-to-one-chat? [:current-chat/one-to-one-chat?]
|
(let [input-text-empty? (string/blank? (string/trim (or input-text "")))]
|
||||||
state-text (reagent/atom "")]
|
[react/view {:style (style/root)}
|
||||||
{:component-will-unmount #(when platform/desktop?
|
|
||||||
(re-frame/dispatch [:chat.ui/set-chat-input-text @state-text]))
|
|
||||||
|
|
||||||
:component-did-mount #(when-not (string/blank? input-text) (reset! state-text input-text))}
|
|
||||||
(let [single-line-input? (:singleLineInput result-box)
|
|
||||||
set-text #(reset! state-text %)
|
|
||||||
input-text-empty? (if platform/desktop?
|
|
||||||
(string/blank? state-text)
|
|
||||||
(string/blank? input-text))]
|
|
||||||
[react/view {:style (style/root margin)}
|
|
||||||
[reply-message-view]
|
[reply-message-view]
|
||||||
[react/view {:style style/input-container}
|
[react/view {:style style/input-container}
|
||||||
[input-view {:single-line-input? single-line-input? :set-text set-text :state-text state-text}]
|
[basic-text-input input-text cooldown-enabled?]
|
||||||
(when (and input-text-empty? mainnet?)
|
(when (and input-text-empty? mainnet?)
|
||||||
[stickers/button (= :stickers input-bottom-sheet)])
|
[stickers/button (= :stickers input-bottom-sheet)])
|
||||||
(when (and one-to-one-chat? input-text-empty? (or config/commands-enabled? mainnet?))
|
(when (and one-to-one-chat? input-text-empty? (or config/commands-enabled? mainnet?))
|
||||||
[extensions/button (= :extensions input-bottom-sheet)])
|
[extensions/button (= :extensions input-bottom-sheet)])
|
||||||
(when-not input-text-empty?
|
(when-not input-text-empty?
|
||||||
(if platform/desktop?
|
[send-button/send-button-view input-text-empty?
|
||||||
[send-button/send-button-view {:input-text @state-text}
|
#(re-frame/dispatch [:chat.ui/send-current-message])])]])))
|
||||||
#(do
|
|
||||||
(re-frame/dispatch [:chat.ui/set-chat-input-text @state-text])
|
|
||||||
(re-frame/dispatch [:chat.ui/send-current-message])
|
|
||||||
(set-text ""))]
|
|
||||||
[send-button/send-button-view {:input-text input-text}
|
|
||||||
#(re-frame/dispatch [:chat.ui/send-current-message])]))]])))
|
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
(ns status-im.ui.screens.chat.input.send-button
|
(ns status-im.ui.screens.chat.input.send-button
|
||||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||||
(:require [clojure.string :as string]
|
(:require [status-im.ui.screens.chat.styles.input.send-button :as style]
|
||||||
[status-im.ui.screens.chat.styles.input.send-button :as style]
|
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||||
[status-im.ui.components.colors :as colors]))
|
[status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
(defn sendable? [input-text disconnected? login-processing?]
|
(defn sendable? [input-text-empty? disconnected? login-processing?]
|
||||||
(let [trimmed (string/trim input-text)]
|
(not (or input-text-empty?
|
||||||
(not (or (string/blank? trimmed)
|
login-processing?
|
||||||
login-processing?
|
disconnected?)))
|
||||||
disconnected?))))
|
|
||||||
|
|
||||||
(defview send-button-view [{:keys [input-text]} on-send-press]
|
(defview send-button-view [input-text-empty? on-send-press]
|
||||||
(letsubs [disconnected? [:disconnected?]
|
(letsubs [disconnected? [:disconnected?]
|
||||||
{:keys [processing]} [:multiaccounts/login]]
|
{:keys [processing]} [:multiaccounts/login]]
|
||||||
(when (sendable? input-text disconnected? processing)
|
(when (sendable? input-text-empty? disconnected? processing)
|
||||||
[react/touchable-highlight
|
[react/touchable-highlight
|
||||||
{:on-press on-send-press}
|
{:on-press on-send-press}
|
||||||
[vector-icons/icon :main-icons/arrow-up
|
[vector-icons/icon :main-icons/arrow-up
|
||||||
|
|
|
@ -137,12 +137,11 @@
|
||||||
:background-color colors/blue}}]))
|
:background-color colors/blue}}]))
|
||||||
|
|
||||||
(defview stickers-view []
|
(defview stickers-view []
|
||||||
(letsubs [selected-pack [:stickers/selected-pack]
|
(letsubs [selected-pack [:stickers/selected-pack]
|
||||||
installed-packs [:stickers/installed-packs-vals]
|
installed-packs [:stickers/installed-packs-vals]
|
||||||
panel-height [:chats/chat-panel-height]
|
panel-height [:chats/chat-panel-height]
|
||||||
|
bottom-anim-value (anim/create-value @panel-height)
|
||||||
bottom-anim-value (anim/create-value @panel-height)
|
alpha-value (anim/create-value 0)]
|
||||||
alpha-value (anim/create-value 0)]
|
|
||||||
{:component-did-mount #(show-panel-anim bottom-anim-value alpha-value)}
|
{:component-did-mount #(show-panel-anim bottom-anim-value alpha-value)}
|
||||||
[react/animated-view {:style {:background-color colors/white
|
[react/animated-view {:style {:background-color colors/white
|
||||||
:height panel-height
|
:height panel-height
|
||||||
|
|
|
@ -8,26 +8,25 @@
|
||||||
(def border-height 1)
|
(def border-height 1)
|
||||||
(def max-input-height (* 5 min-input-height))
|
(def max-input-height (* 5 min-input-height))
|
||||||
|
|
||||||
(defn root [margin-bottom]
|
(defn root []
|
||||||
{:background-color colors/white
|
{:background-color colors/white
|
||||||
:margin-bottom margin-bottom
|
|
||||||
:flex-direction :column
|
:flex-direction :column
|
||||||
:border-top-width border-height
|
:border-top-width border-height
|
||||||
:border-top-color colors/gray-lighter})
|
:border-top-color colors/gray-lighter})
|
||||||
|
|
||||||
(def reply-message
|
(def reply-message
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:align-items :flex-start
|
:align-items :flex-start
|
||||||
:justify-content :space-between
|
:justify-content :space-between
|
||||||
:padding-top 8
|
:padding-top 8
|
||||||
:padding-bottom 8
|
:padding-bottom 8
|
||||||
:padding-right 8
|
:padding-right 8
|
||||||
:padding-left 8})
|
:padding-left 8})
|
||||||
|
|
||||||
(def reply-message-content
|
(def reply-message-content
|
||||||
{:flex-direction :column
|
{:flex-direction :column
|
||||||
:padding-left 8
|
:padding-left 8
|
||||||
:padding-right 8
|
:padding-right 8
|
||||||
:max-height 140})
|
:max-height 140})
|
||||||
|
|
||||||
(defn reply-message-author [chosen?]
|
(defn reply-message-author [chosen?]
|
||||||
|
@ -45,46 +44,40 @@
|
||||||
{:flex-direction :column-reverse})
|
{:flex-direction :column-reverse})
|
||||||
|
|
||||||
(def reply-message-to-container
|
(def reply-message-to-container
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:height 18
|
:height 18
|
||||||
:padding-top 0
|
:padding-top 0
|
||||||
:padding-bottom 0
|
:padding-bottom 0
|
||||||
:padding-right 8
|
:padding-right 8
|
||||||
:justify-content :flex-start})
|
:justify-content :flex-start})
|
||||||
|
|
||||||
(def reply-icon
|
(def reply-icon
|
||||||
{:width 20
|
{:width 20
|
||||||
:margin-top 1
|
:margin-top 1
|
||||||
:margin-bottom 1
|
:margin-bottom 1
|
||||||
:margin-right 0})
|
:margin-right 0})
|
||||||
|
|
||||||
(def cancel-reply-highlight
|
(def cancel-reply-highlight
|
||||||
{:align-self :flex-start
|
{:align-self :flex-start
|
||||||
:width 19
|
:width 19
|
||||||
:height 19})
|
:height 19})
|
||||||
|
|
||||||
(def cancel-reply-container
|
(def cancel-reply-container
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:justify-content :flex-end
|
:justify-content :flex-end
|
||||||
:height "100%"})
|
:height "100%"})
|
||||||
|
|
||||||
(def cancel-reply-icon
|
(def cancel-reply-icon
|
||||||
{:background-color colors/gray
|
{:background-color colors/gray
|
||||||
:width 21
|
:width 21
|
||||||
:height 21
|
:height 21
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
:border-radius 12})
|
:border-radius 12})
|
||||||
|
|
||||||
(def input-container
|
(def input-container
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:align-items :flex-end
|
:align-items :flex-end})
|
||||||
:padding-left 14})
|
|
||||||
|
|
||||||
(def input-root
|
|
||||||
{:padding-top padding-vertical
|
|
||||||
:padding-bottom padding-vertical
|
|
||||||
:flex 1})
|
|
||||||
|
|
||||||
(def input-animated
|
(def input-animated
|
||||||
{:align-items :flex-start
|
{:align-items :flex-start
|
||||||
|
@ -93,16 +86,13 @@
|
||||||
:min-height min-input-height
|
:min-height min-input-height
|
||||||
:max-height max-input-height})
|
:max-height max-input-height})
|
||||||
|
|
||||||
(styles/defn input-view [single-line-input?]
|
(def input-view
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:padding-top 9
|
:padding-top 12
|
||||||
:padding-bottom 5
|
:padding-bottom 15
|
||||||
:padding-right 12
|
:padding-horizontal 12
|
||||||
:min-height min-input-height
|
:min-height min-input-height
|
||||||
:max-height (if single-line-input?
|
:max-height max-input-height})
|
||||||
min-input-height
|
|
||||||
max-input-height)
|
|
||||||
:android {:padding-top 3}})
|
|
||||||
|
|
||||||
(def invisible-input-text
|
(def invisible-input-text
|
||||||
{:position :absolute
|
{:position :absolute
|
||||||
|
|
|
@ -136,6 +136,10 @@
|
||||||
:on-scroll-to-index-failed #() ;;don't remove this
|
:on-scroll-to-index-failed #() ;;don't remove this
|
||||||
:keyboard-should-persist-taps :handled}]))
|
:keyboard-should-persist-taps :handled}]))
|
||||||
|
|
||||||
|
(defview empty-bottom-sheet []
|
||||||
|
(letsubs [input-bottom-sheet [:chats/empty-chat-panel-height]]
|
||||||
|
[react/view {:height input-bottom-sheet}]))
|
||||||
|
|
||||||
(defview bottom-sheet []
|
(defview bottom-sheet []
|
||||||
(letsubs [input-bottom-sheet [:chats/current-chat-ui-prop :input-bottom-sheet]]
|
(letsubs [input-bottom-sheet [:chats/current-chat-ui-prop :input-bottom-sheet]]
|
||||||
(case input-bottom-sheet
|
(case input-bottom-sheet
|
||||||
|
@ -143,7 +147,7 @@
|
||||||
[stickers/stickers-view]
|
[stickers/stickers-view]
|
||||||
:extensions
|
:extensions
|
||||||
[extensions/extensions-view]
|
[extensions/extensions-view]
|
||||||
nil)))
|
[empty-bottom-sheet])))
|
||||||
|
|
||||||
(defview chat []
|
(defview chat []
|
||||||
(letsubs [{:keys [chat-id show-input? group-chat contact] :as current-chat}
|
(letsubs [{:keys [chat-id show-input? group-chat contact] :as current-chat}
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
:mailserver/topics {}
|
:mailserver/topics {}
|
||||||
:mailserver/pending-requests 0
|
:mailserver/pending-requests 0
|
||||||
:chat/cooldowns 0
|
:chat/cooldowns 0
|
||||||
|
:chat/inputs {}
|
||||||
:chat/cooldown-enabled? false
|
:chat/cooldown-enabled? false
|
||||||
:chat/last-outgoing-message-sent-at 0
|
:chat/last-outgoing-message-sent-at 0
|
||||||
:chat/spam-messages-frequency 0
|
:chat/spam-messages-frequency 0
|
||||||
|
@ -203,6 +204,7 @@
|
||||||
:browser/options
|
:browser/options
|
||||||
:navigation/screen-params
|
:navigation/screen-params
|
||||||
:chat/cooldowns
|
:chat/cooldowns
|
||||||
|
:chat/inputs
|
||||||
:chat/cooldown-enabled?
|
:chat/cooldown-enabled?
|
||||||
:chat/last-outgoing-message-sent-at
|
:chat/last-outgoing-message-sent-at
|
||||||
:chat/spam-messages-frequency
|
:chat/spam-messages-frequency
|
||||||
|
|
Loading…
Reference in New Issue