Optimized ScrollView instead of FlatList for desktop chat
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
parent
68fc93a935
commit
add759711a
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -271,3 +271,5 @@
|
|||
(def decline-chat
|
||||
{:color colors/blue
|
||||
:margin-bottom 40})
|
||||
|
||||
(def messages-list-vertical-padding 46)
|
|
@ -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?
|
||||
|
|
Loading…
Reference in New Issue