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)}))]))
|
{: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]}]
|
(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
|
[react/text-input
|
||||||
(merge
|
(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
|
:accessibility-label :chat-message-input
|
||||||
:multiline (not single-line-input?)
|
:multiline (not single-line-input?)
|
||||||
:default-value @state-text
|
:default-value @state-text
|
||||||
|
@ -68,6 +71,8 @@
|
||||||
:on-blur #(re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-focused? false}])
|
:on-blur #(re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-focused? false}])
|
||||||
:submit-shortcut {:key "Enter"}
|
:submit-shortcut {:key "Enter"}
|
||||||
:on-submit-editing #(do
|
: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/set-chat-input-text @state-text])
|
||||||
(re-frame/dispatch [:chat.ui/send-current-message])
|
(re-frame/dispatch [:chat.ui/send-current-message])
|
||||||
(set-text ""))
|
(set-text ""))
|
||||||
|
@ -200,8 +205,13 @@
|
||||||
(if input-text-empty?
|
(if input-text-empty?
|
||||||
[commands-button]
|
[commands-button]
|
||||||
(if platform/desktop?
|
(if platform/desktop?
|
||||||
[send-button/send-button-view {:input-text @state-text}]
|
[send-button/send-button-view {:input-text @state-text}
|
||||||
[send-button/send-button-view {:input-text input-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 []
|
(defn container []
|
||||||
[react/view
|
[react/view
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
login-processing?
|
login-processing?
|
||||||
disconnected?))))
|
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]
|
(letsubs [{:keys [command-completion]} [:chats/selected-chat-command]
|
||||||
disconnected? [:disconnected?]
|
disconnected? [:disconnected?]
|
||||||
{:keys [processing]} [:accounts/login]]
|
{:keys [processing]} [:accounts/login]]
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
(or (not command-completion)
|
(or (not command-completion)
|
||||||
(#{:complete :less-than-needed} command-completion)))
|
(#{:complete :less-than-needed} command-completion)))
|
||||||
[react/touchable-highlight
|
[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
|
[vector-icons/icon :main-icons/arrow-up
|
||||||
{:container-style style/send-message-container
|
{:container-style style/send-message-container
|
||||||
:accessibility-label :send-message-button
|
:accessibility-label :send-message-button
|
||||||
|
|
|
@ -4,12 +4,13 @@
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.utils.datetime :as datetime]
|
[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
|
(defn on-press
|
||||||
[ids first-gap? idx list-ref]
|
[ids first-gap? idx list-ref]
|
||||||
(fn []
|
(fn []
|
||||||
(when (and list-ref @list-ref)
|
(when (and list-ref @list-ref (not platform/desktop?))
|
||||||
(.scrollToIndex @list-ref
|
(.scrollToIndex @list-ref
|
||||||
#js {:index (max 0 (dec idx))
|
#js {:index (max 0 (dec idx))
|
||||||
:viewOffset 20
|
:viewOffset 20
|
||||||
|
|
|
@ -271,3 +271,5 @@
|
||||||
(def decline-chat
|
(def decline-chat
|
||||||
{:color colors/blue
|
{:color colors/blue
|
||||||
:margin-bottom 40})
|
:margin-bottom 40})
|
||||||
|
|
||||||
|
(def messages-list-vertical-padding 46)
|
|
@ -1,5 +1,6 @@
|
||||||
(ns status-im.ui.screens.chat.views
|
(ns status-im.ui.screens.chat.views
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[reagent.core :as reagent]
|
||||||
[status-im.chat.models :as models.chat]
|
[status-im.chat.models :as models.chat]
|
||||||
[status-im.contact.db :as contact.db]
|
[status-im.contact.db :as contact.db]
|
||||||
[status-im.group-chats.db :as group-chats.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 (merge flat-list-conf group-header)]
|
||||||
[list/flat-list flat-list-conf]))))
|
[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]
|
(defn show-input-container? [my-public-key current-chat]
|
||||||
(or (not (models.chat/group-chat? current-chat))
|
(or (not (models.chat/group-chat? current-chat))
|
||||||
(group-chats.db/joined? my-public-key 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)]))}
|
(re-frame/dispatch [:set :layout-height (-> e .-nativeEvent .-layout .-height)]))}
|
||||||
[chat-toolbar current-chat public? modal?]
|
[chat-toolbar current-chat public? modal?]
|
||||||
[messages-view-animation
|
[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)
|
(when (show-input-container? my-public-key current-chat)
|
||||||
[input/container])
|
[input/container])
|
||||||
(when show-stickers?
|
(when show-stickers?
|
||||||
|
|
Loading…
Reference in New Issue