Alexander Pantyukhov 74f9ea32a3
[fix #1604]: Commands send, request, location are sent several times if quickly tap on send button
Signed-off-by: Dmitry Novotochinov <trybeee@gmail.com>
2018-02-01 19:16:53 +03:00

131 lines
6.2 KiB
Clojure

(ns status-im.chat.screen
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.chat.styles.screen :as style]
[status-im.utils.datetime :as time]
[status-im.utils.platform :as platform]
[status-im.chat.views.toolbar-content :as toolbar-content]
[status-im.chat.views.message.message :as message]
[status-im.chat.views.message.datemark :as message-datemark]
[status-im.chat.views.input.input :as input]
[status-im.chat.views.actions :as actions]
[status-im.chat.views.bottom-info :as bottom-info]
[status-im.i18n :as i18n]
[status-im.ui.components.react :as react]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.chat-icon.screen :as chat-icon-screen]
[status-im.ui.components.animation :as anim]
[status-im.ui.components.animation :as anim]
[status-im.ui.components.sync-state.offline :as offline]
[status-im.ui.components.toolbar.view :as toolbar]))
(defview chat-icon []
(letsubs [{:keys [chat-id group-chat name color]} [:get-current-chat]]
[chat-icon-screen/chat-icon-view-action chat-id group-chat name color true]))
(defn- toolbar-action [show-actions?]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:set-chat-ui-props {:show-actions? (not show-actions?)}])
:accessibility-label :chat-menu}
[react/view style/action
(if show-actions?
[vector-icons/icon :icons/dropdown-up]
[chat-icon])]])
(defview add-contact-bar []
(letsubs [chat-id [:get-current-chat-id]
pending-contact? [:current-contact :pending?]]
(when pending-contact?
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:add-pending-contact chat-id])}
[react/view style/add-contact
[react/text {:style style/add-contact-text}
(i18n/label :t/add-to-contacts)]]])))
(defview chat-toolbar []
(letsubs [show-actions? [:get-current-chat-ui-prop :show-actions?]
accounts [:get-accounts]
creating? [:get :accounts/creating-account?]]
[react/view
[status-bar/status-bar]
[toolbar/toolbar {:show-sync-bar? true}
(when-not (or show-actions? creating?)
(if (empty? accounts)
[toolbar/nav-clear-text (i18n/label :t/recover)
#(re-frame/dispatch [:navigate-to-modal :recover-modal])]
toolbar/default-nav-back))
[toolbar-content/toolbar-content-view]
[toolbar-action show-actions?]]
[add-contact-bar]]))
(defmulti message-row (fn [{{:keys [type]} :row}] type))
(defmethod message-row :datemark
[{{:keys [value]} :row}]
[message-datemark/chat-datemark value])
(defmethod message-row :default
[{:keys [group-chat current-public-key row]}]
[message/chat-message (assoc row
:group-chat group-chat
:current-public-key current-public-key)])
(defview messages-view-animation [message-view]
;; smooths out appearance of message-view
(letsubs [opacity (anim/create-value 0)
duration (if platform/android? 100 200)
timeout (if platform/android? 50 0)]
{:component-did-mount (fn [component]
(anim/start
(anim/anim-sequence
[(anim/anim-delay timeout)
(anim/spring opacity {:toValue 1
:duration duration})])))}
[react/with-activity-indicator
{:style style/message-view-preview
:preview [react/view style/message-view-preview]}
[react/animated-view {:style (style/message-view-animated opacity)}
message-view]]))
(defview messages-view [group-chat]
(letsubs [messages [:get-current-chat-messages]
current-public-key [:get-current-public-key]]
[list/flat-list {:data messages
:render-fn (fn [{:keys [message-id] :as message}]
^{:key message-id}
[message-row {:group-chat group-chat
:current-public-key current-public-key
:row message}])
:inverted true
:onEndReached #(re-frame/dispatch [:load-more-messages])
:enableEmptySections true
:keyboardShouldPersistTaps (if platform/android? :always :handled)}]))
(defview chat []
(letsubs [{:keys [group-chat input-text]} [:get-current-chat]
show-actions? [:get-current-chat-ui-prop :show-actions?]
show-bottom-info? [:get-current-chat-ui-prop :show-bottom-info?]
show-emoji? [:get-current-chat-ui-prop :show-emoji?]
layout-height [:get :layout-height]
current-view [:get :view-id]]
{:component-will-unmount #(re-frame/dispatch [:set-chat-ui-props {:show-emoji? false}])}
[react/view {:style style/chat-view
:on-layout (fn [event]
(let [height (.. event -nativeEvent -layout -height)]
(when (not= height layout-height)
(re-frame/dispatch [:set-layout-height height]))))}
[chat-toolbar]
(when (= :chat current-view)
[messages-view-animation
[messages-view group-chat]])
[input/container {:text-empty? (string/blank? input-text)}]
(when show-actions?
[actions/actions-view])
(when show-bottom-info?
[bottom-info/bottom-info-view])
[offline/offline-view {:top (get platform/platform-specific :status-bar-default-height)}]]))