mirror of
https://github.com/status-im/status-mobile.git
synced 2025-02-22 13:28:45 +00:00
131 lines
6.2 KiB
Clojure
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)}]]))
|