refactor: chat message list context related (#15313)
This commit is contained in:
parent
dabe8285be
commit
9723479634
|
@ -22,11 +22,10 @@
|
|||
(defn get-actions
|
||||
[{:keys [outgoing content pinned outgoing-status deleted? deleted-for-me? content-type]
|
||||
:as message-data}
|
||||
{:keys [edit-enabled show-input? community? can-delete-message-for-everyone?
|
||||
{:keys [able-to-send-message? community? can-delete-message-for-everyone?
|
||||
message-pin-enabled group-chat group-admin?]}]
|
||||
(concat
|
||||
(when (and outgoing
|
||||
edit-enabled
|
||||
(not (or deleted? deleted-for-me?))
|
||||
(not= content-type constants/content-type-audio))
|
||||
[{:type :main
|
||||
|
@ -34,7 +33,7 @@
|
|||
:label (i18n/label :t/edit-message)
|
||||
:icon :i/edit
|
||||
:id :edit}])
|
||||
(when (and show-input? (not= outgoing-status :sending) (not (or deleted? deleted-for-me?)))
|
||||
(when (and able-to-send-message? (not= outgoing-status :sending) (not (or deleted? deleted-for-me?)))
|
||||
[{:type :main
|
||||
:on-press #(rf/dispatch [:chat.ui/reply-to-message message-data])
|
||||
:label (i18n/label :t/message-reply)
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
(defonce messages-list-ref (atom nil))
|
||||
|
||||
(defonce list-key-fn #(or (:message-id %) (:value %)))
|
||||
(defonce list-ref #(reset! messages-list-ref %))
|
||||
(defn list-key-fn [{:keys [message-id value]}] (or message-id value))
|
||||
(defn list-ref [ref] (reset! messages-list-ref ref))
|
||||
|
||||
(defn scroll-to-bottom
|
||||
[]
|
||||
|
@ -68,37 +68,6 @@
|
|||
(background-timer/set-timeout #(rf/dispatch [:chat.ui/load-more-messages-for-current-chat])
|
||||
(if platform/low-device? 700 200))))
|
||||
|
||||
(defn get-render-data
|
||||
"compute data used to render message list, including pinned message list and message list in chats"
|
||||
[{:keys [group-chat chat-id public? community-id admins space-keeper show-input? edit-enabled
|
||||
in-pinned-view?]}]
|
||||
(let [current-public-key (rf/sub [:multiaccount/public-key])
|
||||
{:keys [can-delete-message-for-everyone?
|
||||
admin-settings]
|
||||
:as community} (rf/sub [:communities/community
|
||||
community-id])
|
||||
{:keys [pin-message-all-members-enabled?]} admin-settings
|
||||
group-admin? (get admins current-public-key)
|
||||
community-admin? (when community (community :admin))
|
||||
message-pin-enabled (and (not public?)
|
||||
(or (not group-chat)
|
||||
(and group-chat
|
||||
(or group-admin?
|
||||
pin-message-all-members-enabled?
|
||||
community-admin?))))]
|
||||
{:group-chat group-chat
|
||||
:group-admin? group-admin?
|
||||
:public? public?
|
||||
:community? (not (nil? community-id))
|
||||
:current-public-key current-public-key
|
||||
:space-keeper space-keeper
|
||||
:chat-id chat-id
|
||||
:show-input? show-input?
|
||||
:message-pin-enabled message-pin-enabled
|
||||
:edit-enabled edit-enabled
|
||||
:in-pinned-view? in-pinned-view?
|
||||
:can-delete-message-for-everyone? can-delete-message-for-everyone?}))
|
||||
|
||||
(defonce messages-view-height (reagent/atom 0))
|
||||
|
||||
(defn on-messages-view-layout
|
||||
|
@ -133,49 +102,37 @@
|
|||
[message/message-with-reactions message-data context])]))])
|
||||
|
||||
(defn messages-list
|
||||
[{:keys [chat
|
||||
pan-responder
|
||||
show-input?]}]
|
||||
(let [{:keys [group-chat chat-id public? community-id admins]} chat
|
||||
messages (rf/sub [:chats/raw-chat-messages-stream
|
||||
chat-id])
|
||||
bottom-space 15]
|
||||
[{:keys [chat-id] :as chat}]
|
||||
(let [render-data (rf/sub [:chats/current-chat-message-list-view-context])
|
||||
messages (rf/sub [:chats/raw-chat-messages-stream chat-id])
|
||||
bottom-space 15]
|
||||
[rn/view
|
||||
{:style {:flex 1}}
|
||||
;;DO NOT use anonymous functions for handlers
|
||||
;; NOTE: DO NOT use anonymous functions for handlers
|
||||
[rn/flat-list
|
||||
(merge
|
||||
pan-responder
|
||||
{:key-fn list-key-fn
|
||||
:ref list-ref
|
||||
:header [list-header chat]
|
||||
:footer [list-footer chat]
|
||||
:data messages
|
||||
:render-data (get-render-data {:group-chat group-chat
|
||||
:chat-id chat-id
|
||||
:public? public?
|
||||
:community-id community-id
|
||||
:admins admins
|
||||
:show-input? show-input?
|
||||
:edit-enabled true
|
||||
:in-pinned-view? false})
|
||||
:render-fn render-fn
|
||||
:on-viewable-items-changed on-viewable-items-changed
|
||||
:on-end-reached list-on-end-reached
|
||||
:on-scroll-to-index-failed identity ;;don't remove this
|
||||
:content-container-style {:padding-top (+ bottom-space 32)
|
||||
:padding-bottom 16}
|
||||
:scroll-indicator-insets {:top bottom-space} ;;ios only
|
||||
:keyboard-dismiss-mode :interactive
|
||||
:keyboard-should-persist-taps :handled
|
||||
:onMomentumScrollBegin state/start-scrolling
|
||||
:onMomentumScrollEnd state/stop-scrolling
|
||||
:scrollEventThrottle 16
|
||||
:on-scroll on-scroll
|
||||
;;TODO https://github.com/facebook/react-native/issues/30034
|
||||
:inverted (when platform/ios? true)
|
||||
:style (when platform/android? {:scaleY -1})
|
||||
:on-layout on-messages-view-layout})]
|
||||
{:key-fn list-key-fn
|
||||
:ref list-ref
|
||||
:header [list-header chat]
|
||||
:footer [list-footer chat]
|
||||
:data messages
|
||||
:render-data render-data
|
||||
:render-fn render-fn
|
||||
:on-viewable-items-changed on-viewable-items-changed
|
||||
:on-end-reached list-on-end-reached
|
||||
:on-scroll-to-index-failed identity ; don't remove this
|
||||
:content-container-style {:padding-top (+ bottom-space 32)
|
||||
:padding-bottom 16}
|
||||
:scroll-indicator-insets {:top bottom-space} ; iOS only
|
||||
:keyboard-dismiss-mode :interactive
|
||||
:keyboard-should-persist-taps :handled
|
||||
:onMomentumScrollBegin state/start-scrolling
|
||||
:onMomentumScrollEnd state/stop-scrolling
|
||||
:scrollEventThrottle 16
|
||||
:on-scroll on-scroll
|
||||
;; TODO https://github.com/facebook/react-native/issues/30034
|
||||
:inverted (when platform/ios? true)
|
||||
:style (when platform/android? {:scaleY -1})
|
||||
:on-layout on-messages-view-layout}]
|
||||
[quo/floating-shell-button
|
||||
(merge {:jump-to
|
||||
{:on-press #(do
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
[react-native.core :as rn]
|
||||
[status-im2.contexts.chat.messages.content.deleted.view :as content.deleted]
|
||||
[status-im2.contexts.chat.messages.content.view :as message]
|
||||
[status-im2.contexts.chat.messages.list.view :as list.view]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
@ -19,15 +18,11 @@
|
|||
|
||||
(defn pinned-messages-list
|
||||
[chat-id]
|
||||
(let [pinned-messages (rf/sub [:chats/pinned-sorted-list
|
||||
chat-id])
|
||||
current-chat (rf/sub [:chat-by-id chat-id])
|
||||
|
||||
{:keys [group-chat chat-id public? community-id admins]}
|
||||
current-chat
|
||||
|
||||
community (rf/sub [:communities/community
|
||||
community-id])]
|
||||
(let [pinned-messages (rf/sub [:chats/pinned-sorted-list chat-id])
|
||||
render-data (rf/sub [:chats/current-chat-message-list-view-context :in-pinned-view])
|
||||
current-chat (rf/sub [:chat-by-id chat-id])
|
||||
{:keys [community-id]} current-chat
|
||||
community (rf/sub [:communities/community community-id])]
|
||||
[rn/view {:accessibility-label :pinned-messages-list}
|
||||
;; TODO (flexsurfer) this should be a component in quo2
|
||||
;; https://github.com/status-im/status-mobile/issues/14529
|
||||
|
@ -56,17 +51,10 @@
|
|||
{:style {:margin-left 4
|
||||
:margin-right 8}}
|
||||
(str "# " (:chat-name current-chat))]])]
|
||||
(if (> (count pinned-messages) 0)
|
||||
(if (pos? (count pinned-messages))
|
||||
[rn/flat-list
|
||||
{:data pinned-messages
|
||||
:render-data (list.view/get-render-data {:group-chat group-chat
|
||||
:chat-id chat-id
|
||||
:public? public?
|
||||
:community-id community-id
|
||||
:show-input? false
|
||||
:admins admins
|
||||
:edit-enabled true
|
||||
:in-pinned-view? true})
|
||||
:render-data render-data
|
||||
:render-fn message-render-fn
|
||||
:key-fn list-key-fn
|
||||
:separator quo/separator}]
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.chat.messages.composer.view :as composer]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||
[status-im2.contexts.chat.messages.composer.view :as composer]
|
||||
[status-im2.contexts.chat.messages.contact-requests.bottom-drawer :as
|
||||
contact-requests.bottom-drawer]
|
||||
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||
[status-im2.contexts.chat.messages.pin.banner.view :as pin.banner]
|
||||
[status-im2.navigation.state :as navigation.state]
|
||||
[utils.debounce :as debounce]
|
||||
|
@ -67,7 +67,7 @@
|
|||
(defn chat-render
|
||||
[]
|
||||
(let [;;NOTE: we want to react only on these fields, do not use full chat map here
|
||||
{:keys [chat-id contact-request-state group-chat show-input?] :as chat}
|
||||
{:keys [chat-id contact-request-state group-chat able-to-send-message?] :as chat}
|
||||
(rf/sub [:chats/current-chat-chat-view])]
|
||||
[safe-area/consumer
|
||||
(fn [insets]
|
||||
|
@ -76,8 +76,8 @@
|
|||
:keyboardVerticalOffset (- (:bottom insets))}
|
||||
[page-nav]
|
||||
[pin.banner/banner chat-id]
|
||||
[messages.list/messages-list {:chat chat :show-input? show-input?}]
|
||||
(if-not show-input?
|
||||
[messages.list/messages-list chat]
|
||||
(if-not able-to-send-message?
|
||||
[contact-requests.bottom-drawer/view chat-id contact-request-state group-chat]
|
||||
[composer/composer chat-id insets])])]))
|
||||
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
[quo.design-system.colors :as colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.add-new.db :as db]
|
||||
[status-im2.contexts.chat.events :as chat.events]
|
||||
[status-im.chat.models.mentions :as mentions]
|
||||
[status-im.communities.core :as communities]
|
||||
[status-im.group-chats.core :as group-chat]
|
||||
[status-im.group-chats.db :as group-chats.db]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im2.config :as config]
|
||||
[status-im.utils.image-server :as image-server]
|
||||
[status-im2.constants :as constants]))
|
||||
[status-im2.config :as config]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.chat.events :as chat.events]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/chat
|
||||
|
@ -178,21 +178,21 @@
|
|||
(when current-chat
|
||||
(cond-> current-chat
|
||||
(chat.events/public-chat? current-chat)
|
||||
(assoc :show-input? true)
|
||||
(assoc :able-to-send-message? true)
|
||||
|
||||
(and (chat.events/group-chat? current-chat)
|
||||
(group-chats.db/member? my-public-key current-chat))
|
||||
(assoc :show-input? true
|
||||
:member? true)
|
||||
(assoc :able-to-send-message? true
|
||||
:member? true)
|
||||
|
||||
(and (chat.events/community-chat? current-chat)
|
||||
(communities/can-post? community my-public-key (:chat-id current-chat)))
|
||||
(assoc :show-input? true)
|
||||
(assoc :able-to-send-message? true)
|
||||
|
||||
(not group-chat)
|
||||
(assoc
|
||||
:contact-request-state (get-in contacts [chat-id :contact-request-state])
|
||||
:show-input?
|
||||
:able-to-send-message?
|
||||
(and
|
||||
(or
|
||||
(get-in inputs [chat-id :metadata :sending-contact-request])
|
||||
|
@ -206,7 +206,7 @@
|
|||
(fn [current-chat]
|
||||
(select-keys current-chat
|
||||
[:chat-id
|
||||
:show-input?
|
||||
:able-to-send-message?
|
||||
:group-chat
|
||||
:admins
|
||||
:invitation-admin
|
||||
|
@ -220,6 +220,44 @@
|
|||
:community-id
|
||||
:emoji])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-message-list-view-context
|
||||
:<- [:chats/current-chat-chat-view]
|
||||
:<- [:communities/current-community]
|
||||
:<- [:multiaccount/public-key]
|
||||
(fn [[current-chat current-community current-public-key] [_ in-pinned-view?]]
|
||||
(let [{:keys [group-chat chat-id public? admins space-keeper able-to-send-message?]}
|
||||
current-chat
|
||||
|
||||
{:keys [can-delete-message-for-everyone? admin-settings]}
|
||||
current-community
|
||||
|
||||
{:keys [pin-message-all-members-enabled?]} admin-settings
|
||||
community? (some? current-community)
|
||||
group-admin? (contains? admins current-public-key)
|
||||
community-admin? (get current-community :admin false)
|
||||
|
||||
message-pin-enabled
|
||||
(cond public? false
|
||||
(not group-chat) true ; one to one chat
|
||||
;; in public group or community
|
||||
group-chat (or group-admin?
|
||||
pin-message-all-members-enabled?
|
||||
community-admin?)
|
||||
:else false)]
|
||||
{:group-chat group-chat
|
||||
:group-admin? group-admin?
|
||||
:public? public?
|
||||
:community? community?
|
||||
:community-admin? community-admin?
|
||||
:current-public-key current-public-key
|
||||
:space-keeper space-keeper
|
||||
:chat-id chat-id
|
||||
:in-pinned-view? (boolean in-pinned-view?)
|
||||
:able-to-send-message? able-to-send-message?
|
||||
:message-pin-enabled message-pin-enabled
|
||||
:can-delete-message-for-everyone? can-delete-message-for-everyone?})))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:current-chat/metadata
|
||||
:<- [:chats/current-raw-chat]
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
(ns status-im2.subs.chat.chats-test
|
||||
(:require [cljs.test :refer [is testing]]
|
||||
[re-frame.db :as rf-db]
|
||||
[test-helpers.unit :as h]
|
||||
[status-im2.constants :as constants]
|
||||
[test-helpers.unit :as h]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def public-key "0xpk")
|
||||
(def multiaccount {:public-key public-key})
|
||||
(def chat-id "1")
|
||||
(def chat {:chat-id chat-id})
|
||||
(def community-id "community-1")
|
||||
(def community {:community-id community-id})
|
||||
|
||||
(def private-group-chat
|
||||
(assoc
|
||||
|
@ -17,6 +19,13 @@
|
|||
:group-chat true
|
||||
:chat-type constants/private-group-chat-type))
|
||||
|
||||
(def community-chat
|
||||
(assoc
|
||||
chat
|
||||
:group-chat true
|
||||
:community-id community-id
|
||||
:chat-type constants/community-chat-type))
|
||||
|
||||
(def one-to-one-chat
|
||||
(assoc
|
||||
chat
|
||||
|
@ -31,14 +40,14 @@
|
|||
:multiaccount multiaccount
|
||||
:current-chat-id chat-id
|
||||
:chats chats)
|
||||
(is (true? (:show-input? (rf/sub [sub-name]))))))
|
||||
(is (true? (:able-to-send-message? (rf/sub [sub-name]))))))
|
||||
(testing "private group chat, user is not member"
|
||||
(let [chats {chat-id (dissoc private-group-chat :members)}]
|
||||
(swap! rf-db/app-db assoc
|
||||
:multiaccount multiaccount
|
||||
:current-chat-id chat-id
|
||||
:chats chats)
|
||||
(is (not (:show-input? (rf/sub [sub-name]))))))
|
||||
(is (not (:able-to-send-message? (rf/sub [sub-name]))))))
|
||||
(testing "one to one chat, mutual contacts"
|
||||
(let [chats {chat-id one-to-one-chat}]
|
||||
(swap! rf-db/app-db assoc
|
||||
|
@ -46,7 +55,7 @@
|
|||
:multiaccount multiaccount
|
||||
:current-chat-id chat-id
|
||||
:chats chats)
|
||||
(is (:show-input? (rf/sub [sub-name])))))
|
||||
(is (:able-to-send-message? (rf/sub [sub-name])))))
|
||||
(testing "one to one chat, not a contact"
|
||||
(let [chats {chat-id one-to-one-chat}]
|
||||
(swap! rf-db/app-db assoc
|
||||
|
@ -54,4 +63,100 @@
|
|||
:multiaccount multiaccount
|
||||
:current-chat-id chat-id
|
||||
:chats chats)
|
||||
(is (not (:show-input? (rf/sub [sub-name])))))))
|
||||
(is (not (:able-to-send-message? (rf/sub [sub-name])))))))
|
||||
|
||||
(h/deftest-sub :chats/current-chat-message-list-view-context
|
||||
[sub-name]
|
||||
(testing "reflect :in-pinned-view? in the result"
|
||||
(reset! rf-db/app-db {})
|
||||
(is (true? (:in-pinned-view? (rf/sub [sub-name :in-pinned-view]))))
|
||||
(is (false? (:in-pinned-view? (rf/sub [sub-name])))))
|
||||
(testing "reflect current community in community?"
|
||||
(let [chats {chat-id community-chat}
|
||||
communities {community-id community}]
|
||||
(is (false? (:community? (rf/sub [sub-name]))))
|
||||
(swap! rf-db/app-db assoc
|
||||
:communities/enabled? true
|
||||
:current-chat-id chat-id
|
||||
:chats chats
|
||||
:communities communities)
|
||||
(is (true? (:community? (rf/sub [sub-name]))))))
|
||||
(testing "community admin"
|
||||
(let [chats {chat-id community-chat}
|
||||
communities {community-id (assoc community
|
||||
:admin true
|
||||
:can-delete-message-for-everyone? true
|
||||
:admin-settings {:pin-message-all-members-enabled? false})}]
|
||||
(is (false? (:community? (rf/sub [sub-name]))))
|
||||
(swap! rf-db/app-db assoc
|
||||
:communities/enabled? true
|
||||
:multiaccount multiaccount
|
||||
:current-chat-id chat-id
|
||||
:chats chats
|
||||
:communities communities)
|
||||
(is (= chat-id (:chat-id (rf/sub [sub-name]))))
|
||||
(is (= public-key (:current-public-key (rf/sub [sub-name]))))
|
||||
(is (true? (:community? (rf/sub [sub-name]))))
|
||||
(is (true? (:group-chat (rf/sub [sub-name]))))
|
||||
(is (true? (:community-admin? (rf/sub [sub-name]))))
|
||||
(is (true? (:can-delete-message-for-everyone? (rf/sub [sub-name]))))
|
||||
(is (not (:group-admin? (rf/sub [sub-name]))))
|
||||
(is (true? (:message-pin-enabled (rf/sub [sub-name]))))))
|
||||
(testing "community member"
|
||||
(let [chats {chat-id community-chat}
|
||||
communities {community-id (assoc community
|
||||
:admin false
|
||||
:can-delete-message-for-everyone? false
|
||||
:admin-settings {:pin-message-all-members-enabled?
|
||||
false})}]
|
||||
(is (false? (:community? (rf/sub [sub-name]))))
|
||||
(swap! rf-db/app-db assoc
|
||||
:communities/enabled? true
|
||||
:multiaccount multiaccount
|
||||
:current-chat-id chat-id
|
||||
:chats chats
|
||||
:communities communities)
|
||||
(is (= chat-id (:chat-id (rf/sub [sub-name]))))
|
||||
(is (= public-key (:current-public-key (rf/sub [sub-name]))))
|
||||
(is (true? (:community? (rf/sub [sub-name]))))
|
||||
(is (true? (:group-chat (rf/sub [sub-name]))))
|
||||
(is (not (:community-admin? (rf/sub [sub-name]))))
|
||||
(is (not (:can-delete-message-for-everyone? (rf/sub [sub-name]))))
|
||||
(is (not (:group-admin? (rf/sub [sub-name]))))
|
||||
(is (not (:message-pin-enabled (rf/sub [sub-name]))))))
|
||||
(testing "group admin"
|
||||
(let [chats {chat-id (assoc private-group-chat
|
||||
:admins
|
||||
#{public-key})}]
|
||||
(swap! rf-db/app-db assoc
|
||||
:communities/enabled? true
|
||||
:multiaccount multiaccount
|
||||
:current-chat-id chat-id
|
||||
:chats chats)
|
||||
(is (= chat-id (:chat-id (rf/sub [sub-name]))))
|
||||
(is (= public-key (:current-public-key (rf/sub [sub-name]))))
|
||||
(is (not (:public? (rf/sub [sub-name]))))
|
||||
(is (not (:community? (rf/sub [sub-name]))))
|
||||
(is (true? (:group-chat (rf/sub [sub-name]))))
|
||||
(is (not (:community-admin? (rf/sub [sub-name]))))
|
||||
(is (not (:can-delete-message-for-everyone? (rf/sub [sub-name]))))
|
||||
(is (true? (:group-admin? (rf/sub [sub-name]))))
|
||||
(is (true? (:message-pin-enabled (rf/sub [sub-name]))))))
|
||||
(testing "group member"
|
||||
(let [chats {chat-id (assoc private-group-chat
|
||||
:admins
|
||||
#{})}]
|
||||
(swap! rf-db/app-db assoc
|
||||
:communities/enabled? true
|
||||
:multiaccount multiaccount
|
||||
:current-chat-id chat-id
|
||||
:chats chats)
|
||||
(is (= chat-id (:chat-id (rf/sub [sub-name]))))
|
||||
(is (= public-key (:current-public-key (rf/sub [sub-name]))))
|
||||
(is (not (:public? (rf/sub [sub-name]))))
|
||||
(is (not (:community? (rf/sub [sub-name]))))
|
||||
(is (true? (:group-chat (rf/sub [sub-name]))))
|
||||
(is (not (:community-admin? (rf/sub [sub-name]))))
|
||||
(is (not (:can-delete-message-for-everyone? (rf/sub [sub-name]))))
|
||||
(is (not (:group-admin? (rf/sub [sub-name]))))
|
||||
(is (not (:message-pin-enabled (rf/sub [sub-name])))))))
|
||||
|
|
Loading…
Reference in New Issue