Optimized ScrollView instead of FlatList for desktop chat

Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
Volodymyr Kozieiev 2019-05-20 18:15:17 +03:00 committed by Andrey Shovkoplyas
parent 68fc93a935
commit add759711a
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
5 changed files with 77 additions and 9 deletions

View File

@ -53,10 +53,13 @@
{: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 [cooldown-enabled? [:chats/cooldown-enabled?]]
(letsubs [inp-ref (atom nil)
cooldown-enabled? [:chats/cooldown-enabled?]]
[react/text-input
(merge
{:ref #(when % (re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-ref %}]))
{: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
@ -68,6 +71,8 @@
:on-blur #(re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-focused? false}])
: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 ""))
@ -200,8 +205,13 @@
(if input-text-empty?
[commands-button]
(if platform/desktop?
[send-button/send-button-view {:input-text @state-text}]
[send-button/send-button-view {:input-text input-text}]))]])))
[send-button/send-button-view {:input-text @state-text}
#(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])]))]])))
(defn container []
[react/view

View File

@ -13,7 +13,7 @@
login-processing?
disconnected?))))
(defview send-button-view [{:keys [input-text]}]
(defview send-button-view [{:keys [input-text]} on-send-press]
(letsubs [{:keys [command-completion]} [:chats/selected-chat-command]
disconnected? [:disconnected?]
{:keys [processing]} [:accounts/login]]
@ -21,7 +21,7 @@
(or (not command-completion)
(#{:complete :less-than-needed} command-completion)))
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:chat.ui/send-current-message])}
{:on-press on-send-press}
[vector-icons/icon :main-icons/arrow-up
{:container-style style/send-message-container
:accessibility-label :send-message-button

View File

@ -4,12 +4,13 @@
[re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.utils.datetime :as datetime]
[status-im.ui.screens.chat.styles.input.gap :as style]))
[status-im.ui.screens.chat.styles.input.gap :as style]
[status-im.utils.platform :as platform]))
(defn on-press
[ids first-gap? idx list-ref]
(fn []
(when (and list-ref @list-ref)
(when (and list-ref @list-ref (not platform/desktop?))
(.scrollToIndex @list-ref
#js {:index (max 0 (dec idx))
:viewOffset 20

View File

@ -271,3 +271,5 @@
(def decline-chat
{:color colors/blue
:margin-bottom 40})
(def messages-list-vertical-padding 46)

View File

@ -1,5 +1,6 @@
(ns status-im.ui.screens.chat.views
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.chat.models :as models.chat]
[status-im.contact.db :as contact.db]
[status-im.group-chats.db :as group-chats.db]
@ -272,6 +273,57 @@
[list/flat-list (merge flat-list-conf group-header)]
[list/flat-list flat-list-conf]))))
(def load-step 5)
(defn load-more [all-messages-count messages-to-load]
(let [next-count (min all-messages-count (+ @messages-to-load load-step))]
(reset! messages-to-load next-count)))
(defview messages-view-desktop [{:keys [chat-id group-chat]}
modal?]
(letsubs [messages [:chats/current-chat-messages-stream]
current-public-key [:account/public-key]
messages-to-load (reagent/atom load-step)
chat-id* (reagent/atom nil)]
{:component-did-update #(if (:messages-initialized? (second (.-argv (.-props %1))))
(load-more (count messages) messages-to-load)
(re-frame/dispatch [:chat.ui/load-more-messages]))
:component-did-mount #(if (:messages-initialized? (second (.-argv (.-props %1))))
(load-more (count messages) messages-to-load)
(re-frame/dispatch [:chat.ui/load-more-messages]))}
(let [messages-list-ref (atom nil)
scroll-timer (atom nil)
scroll-height (atom nil)
_ (when (or (not @chat-id*) (not= @chat-id* chat-id))
(do
(reset! messages-to-load load-step)
(reset! chat-id* chat-id)))]
[react/view {:style style/chat-view}
[react/scroll-view {:scrollEventThrottle 16
:headerHeight style/messages-list-vertical-padding
:footerWidth style/messages-list-vertical-padding
:enableArrayScrollingOptimization true
:inverted true
:ref #(reset! messages-list-ref %)
:on-scroll (fn [e]
(let [ne (.-nativeEvent e)
y (.-y (.-contentOffset ne))]
(when (<= y 0)
(when @scroll-timer (js/clearTimeout @scroll-timer))
(reset! scroll-timer (js/setTimeout #(re-frame/dispatch [:chat.ui/load-more-messages]) 300)))
(reset! scroll-height (+ y (.-height (.-layoutMeasurement ne))))))}
[react/view
(doall
(for [{:keys [from content] :as message-obj} (take @messages-to-load messages)]
^{:key message-obj}
[message-row
{:group-chat group-chat
:modal? modal?
:current-public-key current-public-key
:row message-obj
:idx #(or (:message-id message-obj) (:value message-obj))
:list-ref messages-list-ref}]))]]])))
(defn show-input-container? [my-public-key current-chat]
(or (not (models.chat/group-chat? current-chat))
(group-chats.db/joined? my-public-key current-chat)))
@ -300,7 +352,10 @@
(re-frame/dispatch [:set :layout-height (-> e .-nativeEvent .-layout .-height)]))}
[chat-toolbar current-chat public? modal?]
[messages-view-animation
[messages-view current-chat modal?]]
;;TODO(kozieiev) : When FlatList in react-native-desktop become viable it should be used instead of optimized ScrollView for chat
(if platform/desktop?
[messages-view-desktop current-chat modal?]
[messages-view current-chat modal?])]
(when (show-input-container? my-public-key current-chat)
[input/container])
(when show-stickers?