move reactions events (#18150)
This commit is contained in:
parent
761a7df06f
commit
5570181896
|
@ -178,7 +178,7 @@
|
|||
(when (or first-request cursor)
|
||||
(merge
|
||||
{:db (assoc-in db [:pagination-info chat-id :loading-messages?] true)}
|
||||
{:utils/dispatch-later [{:ms 100 :dispatch [:load-more-reactions cursor chat-id]}]}
|
||||
{:utils/dispatch-later [{:ms 100 :dispatch [:reactions/load-more cursor chat-id]}]}
|
||||
(data-store.messages/messages-by-chat-id-rpc
|
||||
chat-id
|
||||
cursor
|
||||
|
|
|
@ -1,116 +0,0 @@
|
|||
(ns status-im.chat.models.reactions
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.data-store.reactions :as data-store.reactions]
|
||||
[status-im2.constants :as constants]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn update-reaction
|
||||
[acc retracted chat-id message-id emoji-id emoji-reaction-id reaction]
|
||||
;; NOTE(Ferossgp): For a better performance, better to not keep in db all retracted reactions
|
||||
;; retraction will always come after the reaction so there shouldn't be a conflict
|
||||
(if retracted
|
||||
(update-in acc [chat-id message-id emoji-id] dissoc emoji-reaction-id)
|
||||
(assoc-in acc [chat-id message-id emoji-id emoji-reaction-id] reaction)))
|
||||
|
||||
(defn process-reactions
|
||||
[_]
|
||||
(fn [reactions new-reactions]
|
||||
;; TODO(Ferossgp): handling own reaction in subscription could be expensive,
|
||||
;; for better performance we can here separate own reaction into 2 maps
|
||||
(reduce
|
||||
(fn [acc
|
||||
{:keys [chat-id message-id emoji-id emoji-reaction-id retracted]
|
||||
:as reaction}]
|
||||
(update-reaction acc retracted chat-id message-id emoji-id emoji-reaction-id reaction))
|
||||
reactions
|
||||
new-reactions)))
|
||||
|
||||
(defn- earlier-than-deleted-at?
|
||||
[{:keys [db]} {:keys [chat-id clock-value]}]
|
||||
(let [{:keys [deleted-at-clock-value]}
|
||||
(get-in db [:chats chat-id])]
|
||||
(>= deleted-at-clock-value clock-value)))
|
||||
|
||||
(rf/defn receive-signal
|
||||
[{:keys [db] :as cofx} reactions]
|
||||
(let [reactions (filter (partial earlier-than-deleted-at? cofx) reactions)]
|
||||
{:db (update db :reactions (process-reactions (:chats db)) reactions)}))
|
||||
|
||||
(rf/defn load-more-reactions
|
||||
{:events [:load-more-reactions]}
|
||||
[{:keys [db]} cursor chat-id]
|
||||
(when-let [session-id (get-in db [:pagination-info chat-id :messages-initialized?])]
|
||||
(data-store.reactions/reactions-by-chat-id-rpc
|
||||
chat-id
|
||||
cursor
|
||||
constants/default-number-of-messages
|
||||
#(re-frame/dispatch [::reactions-loaded chat-id session-id %])
|
||||
#(log/error "failed loading reactions" chat-id %))))
|
||||
|
||||
(rf/defn reactions-loaded
|
||||
{:events [::reactions-loaded]}
|
||||
[{db :db}
|
||||
chat-id
|
||||
session-id
|
||||
reactions]
|
||||
(when-not (and (get-in db [:pagination-info chat-id :messages-initialized?])
|
||||
(not= session-id
|
||||
(get-in db [:pagination-info chat-id :messages-initialized?])))
|
||||
(let [reactions-w-chat-id (map #(assoc % :chat-id chat-id) reactions)]
|
||||
{:db (update db :reactions (process-reactions (:chats db)) reactions-w-chat-id)})))
|
||||
|
||||
(defn message-reactions
|
||||
[current-public-key reactions]
|
||||
(reduce
|
||||
(fn [acc [emoji-id reactions]]
|
||||
(if (pos? (count reactions))
|
||||
(let [own (first (filter (fn [[_ {:keys [from]}]]
|
||||
(= from current-public-key))
|
||||
reactions))]
|
||||
(conj acc
|
||||
{:emoji-id emoji-id
|
||||
:own (boolean (seq own))
|
||||
:emoji-reaction-id (:emoji-reaction-id (second own))
|
||||
:quantity (count reactions)}))
|
||||
acc))
|
||||
[]
|
||||
reactions))
|
||||
|
||||
(defn- <-rpc
|
||||
[{compressed-key :compressedKey
|
||||
emoji-id :emojiId
|
||||
:keys [from]}]
|
||||
{:compressed-key compressed-key
|
||||
:emoji-id emoji-id
|
||||
:from from})
|
||||
|
||||
(defn- format-response
|
||||
[response]
|
||||
(->> (transforms/js->clj response)
|
||||
(map <-rpc)
|
||||
(group-by :emoji-id)))
|
||||
|
||||
(rf/defn save-emoji-reaction-details
|
||||
{:events [:chat/save-emoji-reaction-details]}
|
||||
[{:keys [db]} reaction-authors]
|
||||
{:db (assoc db :chat/reactions-authors reaction-authors)})
|
||||
|
||||
(rf/defn clear-emoji-reaction-details
|
||||
{:events [:chat/clear-emoji-reaction-author-details]}
|
||||
[{:keys [db]}]
|
||||
{:db (dissoc db :chat/reactions-authors)})
|
||||
|
||||
(rf/defn emoji-reactions-by-message-id
|
||||
{:events [:chat.ui/emoji-reactions-by-message-id]}
|
||||
[{:keys [db]} {:keys [message-id on-success]}]
|
||||
{:db (dissoc db :chat/reactions-authors)
|
||||
:json-rpc/call [{:method "wakuext_emojiReactionsByChatIDMessageID"
|
||||
:params [(:current-chat-id db) message-id]
|
||||
:js-response true
|
||||
:on-error #(log/error "failed to fetch emoji reaction by message-id: "
|
||||
{:message-id message-id :error %})
|
||||
:on-success #(when on-success
|
||||
(on-success (format-response %)))}]})
|
|
@ -1,34 +0,0 @@
|
|||
(ns status-im.data-store.reactions
|
||||
(:require
|
||||
[clojure.set :as set]))
|
||||
|
||||
(defn ->rpc
|
||||
[message]
|
||||
(-> message
|
||||
(set/rename-keys {:message-id :messageId
|
||||
:emoji-id :emojiId
|
||||
:chat-id :localChatId
|
||||
:message-type :messageType
|
||||
:emoji-reaction-id :id})))
|
||||
|
||||
(defn <-rpc
|
||||
[message]
|
||||
(-> message
|
||||
(dissoc :chat_id)
|
||||
(set/rename-keys {:messageId :message-id
|
||||
:localChatId :chat-id
|
||||
:emojiId :emoji-id
|
||||
:messageType :message-type
|
||||
:id :emoji-reaction-id})))
|
||||
|
||||
(defn reactions-by-chat-id-rpc
|
||||
[chat-id
|
||||
cursor
|
||||
limit
|
||||
on-success
|
||||
on-error]
|
||||
{:json-rpc/call [{:method "wakuext_emojiReactionsByChatID"
|
||||
:params [chat-id cursor limit]
|
||||
:on-success (fn [result]
|
||||
(on-success (map <-rpc result)))
|
||||
:on-error on-error}]})
|
|
@ -12,6 +12,7 @@
|
|||
[status-im2.contexts.chat.composer.link-preview.events :as link-preview]
|
||||
status-im2.contexts.chat.effects
|
||||
status-im2.contexts.chat.lightbox.events
|
||||
status-im2.contexts.chat.messages.content.reactions.events
|
||||
[status-im2.contexts.chat.messages.delete-message-for-me.events :as delete-for-me]
|
||||
[status-im2.contexts.chat.messages.delete-message.events :as delete-message]
|
||||
[status-im2.contexts.chat.messages.list.state :as chat.state]
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
(ns status-im2.contexts.chat.messages.content.reactions.events
|
||||
(:require [clojure.set :as set]
|
||||
[status-im2.constants :as constants]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn update-reaction
|
||||
[acc retracted chat-id message-id emoji-id emoji-reaction-id reaction]
|
||||
;; NOTE: For a better performance, better to not keep in db all retracted reactions
|
||||
;; retraction will always come after the reaction so there shouldn't be a conflict
|
||||
(if retracted
|
||||
(update-in acc [chat-id message-id emoji-id] dissoc emoji-reaction-id)
|
||||
(assoc-in acc [chat-id message-id emoji-id emoji-reaction-id] reaction)))
|
||||
|
||||
(defn process-reactions
|
||||
[_]
|
||||
(fn [reactions new-reactions]
|
||||
;; NOTE: handling own reaction in subscription could be expensive,
|
||||
;; for better performance we can here separate own reaction into 2 maps
|
||||
(reduce
|
||||
(fn [acc
|
||||
{:keys [chat-id message-id emoji-id emoji-reaction-id retracted]
|
||||
:as reaction}]
|
||||
(update-reaction acc retracted chat-id message-id emoji-id emoji-reaction-id reaction))
|
||||
reactions
|
||||
new-reactions)))
|
||||
|
||||
(defn- earlier-than-deleted-at?
|
||||
[{:keys [db]} {:keys [chat-id clock-value]}]
|
||||
(let [{:keys [deleted-at-clock-value]}
|
||||
(get-in db [:chats chat-id])]
|
||||
(>= deleted-at-clock-value clock-value)))
|
||||
|
||||
(rf/defn receive-signal
|
||||
[{:keys [db] :as cofx} reactions]
|
||||
(let [reactions (filter (partial earlier-than-deleted-at? cofx) reactions)]
|
||||
{:db (update db :reactions (process-reactions (:chats db)) reactions)}))
|
||||
|
||||
(defn <-rpc
|
||||
[message]
|
||||
(-> message
|
||||
(dissoc :chat_id)
|
||||
(set/rename-keys {:messageId :message-id
|
||||
:localChatId :chat-id
|
||||
:emojiId :emoji-id
|
||||
:messageType :message-type
|
||||
:id :emoji-reaction-id})))
|
||||
|
||||
(rf/reg-event-fx :reactions/load-more
|
||||
(fn [{:keys [db]} [cursor chat-id]]
|
||||
(when-let [session-id (get-in db [:pagination-info chat-id :messages-initialized?])]
|
||||
{:json-rpc/call [{:method "wakuext_emojiReactionsByChatID"
|
||||
:params [chat-id cursor constants/default-number-of-messages]
|
||||
:on-success #(rf/dispatch [:reactions/loaded chat-id session-id (map <-rpc %)])
|
||||
:on-error #(log/error "failed loading reactions" chat-id %)}]})))
|
||||
|
||||
(rf/reg-event-fx :reactions/loaded
|
||||
(fn [{db :db} [chat-id session-id reactions]]
|
||||
(when-not (and (get-in db [:pagination-info chat-id :messages-initialized?])
|
||||
(not= session-id
|
||||
(get-in db [:pagination-info chat-id :messages-initialized?])))
|
||||
(let [reactions-w-chat-id (map #(assoc % :chat-id chat-id) reactions)]
|
||||
{:db (update db :reactions (process-reactions (:chats db)) reactions-w-chat-id)}))))
|
||||
|
||||
(defn- format-authors-response
|
||||
[response]
|
||||
(->> response
|
||||
(map (fn [item]
|
||||
{:compressed-key (:compressedKey item)
|
||||
:emoji-id (:emojiId item)
|
||||
:from (:from item)}))
|
||||
(group-by :emoji-id)))
|
||||
|
||||
(rf/reg-event-fx :reactions/get-authors-by-message-id
|
||||
(fn [{:keys [db]} [{:keys [message-id on-success]}]]
|
||||
{:db (dissoc db :reactions/authors)
|
||||
:json-rpc/call [{:method "wakuext_emojiReactionsByChatIDMessageID"
|
||||
:params [(:current-chat-id db) message-id]
|
||||
:on-error #(log/error "failed to fetch emoji reaction by message-id: "
|
||||
{:message-id message-id :error %})
|
||||
:on-success #(when on-success
|
||||
(on-success (format-authors-response %)))}]}))
|
||||
|
||||
(rf/reg-event-fx :reactions/save-authors
|
||||
(fn [{:keys [db]} [reaction-authors]]
|
||||
{:db (assoc db :reactions/authors reaction-authors)}))
|
||||
|
||||
(rf/reg-event-fx :reactions/clear-authors
|
||||
(fn [{:keys [db]}]
|
||||
{:db (dissoc db :reactions/authors)}))
|
||||
|
||||
(rf/reg-event-fx :reactions/send-emoji-reaction
|
||||
(fn [{{:keys [current-chat-id]} :db} [{:keys [message-id emoji-id]}]]
|
||||
{:json-rpc/call [{:method "wakuext_sendEmojiReaction"
|
||||
:params [current-chat-id message-id emoji-id]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to send a reaction" %)}]}))
|
||||
|
||||
(rf/reg-event-fx :reactions/send-emoji-reaction-retraction
|
||||
(fn [_ [emoji-reaction-id]]
|
||||
{:json-rpc/call [{:method "wakuext_sendEmojiReactionRetraction"
|
||||
:params [emoji-reaction-id]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to send a reaction retraction" %)}]}))
|
|
@ -2,6 +2,7 @@
|
|||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.chat.messages.drawers.view :as drawers]
|
||||
[utils.re-frame :as rf]))
|
||||
|
@ -17,23 +18,21 @@
|
|||
(defn- on-long-press
|
||||
[{:keys [message-id emoji-id user-message-content reactions-order theme]}]
|
||||
(rf/dispatch
|
||||
[:chat.ui/emoji-reactions-by-message-id
|
||||
[:reactions/get-authors-by-message-id
|
||||
{:message-id message-id
|
||||
:on-success (fn [response]
|
||||
(rf/dispatch [:chat/save-emoji-reaction-details
|
||||
(rf/dispatch [:reactions/save-authors
|
||||
{:reaction-authors-list response
|
||||
:selected-reaction emoji-id}])
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:on-close (fn []
|
||||
(rf/dispatch
|
||||
[:chat/clear-emoji-reaction-author-details]))
|
||||
{:on-close #(rf/dispatch
|
||||
[:reactions/clear-authors])
|
||||
:content (fn []
|
||||
[drawers/reaction-authors
|
||||
{:reactions-order reactions-order
|
||||
:theme theme}])
|
||||
:selected-item (fn []
|
||||
user-message-content)
|
||||
:selected-item (fn [] user-message-content)
|
||||
:padding-bottom-override 0}]))}]))
|
||||
|
||||
(defn- on-press-add
|
||||
|
@ -56,7 +55,7 @@
|
|||
(defn- view-internal
|
||||
[{:keys [message-id chat-id pinned-by theme]} user-message-content]
|
||||
(let [reactions (rf/sub [:chats/message-reactions message-id chat-id])]
|
||||
[:<>
|
||||
[rn/view {:border-color :red :border-width 1}
|
||||
(when (seq reactions)
|
||||
[quo/react
|
||||
{:container-style {:margin-left 44
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
(defn reaction-authors
|
||||
[{:keys [reactions-order theme]}]
|
||||
(let [{:keys [reaction-authors-list
|
||||
selected-reaction]} (rf/sub [:chat/reactions-authors])
|
||||
selected-reaction]} (rf/sub [:reactions/authors])
|
||||
selected-tab (reagent/atom (or selected-reaction
|
||||
(first (keys reaction-authors-list))))]
|
||||
(fn []
|
||||
|
|
|
@ -4,12 +4,10 @@
|
|||
[clojure.string :as string]
|
||||
[status-im.browser.core :as browser]
|
||||
[status-im.chat.models.message :as models.message]
|
||||
[status-im.chat.models.reactions :as models.reactions]
|
||||
[status-im.communities.core :as models.communities]
|
||||
[status-im.data-store.activities :as data-store.activities]
|
||||
[status-im.data-store.chats :as data-store.chats]
|
||||
[status-im.data-store.invitations :as data-store.invitations]
|
||||
[status-im.data-store.reactions :as data-store.reactions]
|
||||
[status-im.group-chats.core :as models.group]
|
||||
[status-im.multiaccounts.update.core :as update.core]
|
||||
[status-im.pairing.core :as models.pairing]
|
||||
|
@ -18,6 +16,7 @@
|
|||
[status-im.wallet.core :as wallet]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.chat.events :as chat.events]
|
||||
[status-im2.contexts.chat.messages.content.reactions.events :as reactions]
|
||||
[status-im2.contexts.chat.messages.pin.events :as messages.pin]
|
||||
[status-im2.contexts.contacts.events :as models.contact]
|
||||
[status-im2.contexts.shell.activity-center.events :as activity-center]
|
||||
|
@ -139,7 +138,7 @@
|
|||
(js-delete response-js "emojiReactions")
|
||||
(rf/merge cofx
|
||||
(process-next response-js sync-handler)
|
||||
(models.reactions/receive-signal (map data-store.reactions/<-rpc reactions))))
|
||||
(reactions/receive-signal (map reactions/<-rpc reactions))))
|
||||
|
||||
(seq invitations)
|
||||
(let [invitations (types/js->clj invitations)]
|
||||
|
@ -386,21 +385,3 @@
|
|||
:on-error #(do
|
||||
(log/warn "failed to send a message" %)
|
||||
(js/alert (str "failed to send a message: " %)))}]})
|
||||
|
||||
(rf/defn send-emoji-reaction
|
||||
{:events [:reactions/send-emoji-reaction]}
|
||||
[{{:keys [current-chat-id]} :db} {:keys [message-id emoji-id]}]
|
||||
{:json-rpc/call [{:method "wakuext_sendEmojiReaction"
|
||||
:params [current-chat-id message-id emoji-id]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to send a reaction" %)}]})
|
||||
|
||||
(rf/defn send-retract-emoji-reaction
|
||||
{:events [:reactions/send-emoji-reaction-retraction]}
|
||||
[_ emoji-reaction-id]
|
||||
{:json-rpc/call [{:method "wakuext_sendEmojiReactionRetraction"
|
||||
:params [emoji-reaction-id]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to send a reaction retraction" %)}]})
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
(ns status-im2.subs.messages
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.chat.models.reactions :as models.reactions]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.chat.messages.list.events :as models.message-list]
|
||||
[status-im2.contexts.chat.messages.resolver.message-resolver :as resolver]
|
||||
|
@ -177,9 +176,21 @@
|
|||
:<- [:multiaccount/public-key]
|
||||
:<- [:messages/reactions]
|
||||
(fn [[current-public-key reactions] [_ message-id chat-id]]
|
||||
(models.reactions/message-reactions
|
||||
current-public-key
|
||||
(get-in reactions [chat-id message-id]))))
|
||||
(let [reactions (get-in reactions [chat-id message-id])]
|
||||
(reduce
|
||||
(fn [acc [emoji-id reactions]]
|
||||
(if (pos? (count reactions))
|
||||
(let [own (first (filter (fn [[_ {:keys [from]}]]
|
||||
(= from current-public-key))
|
||||
reactions))]
|
||||
(conj acc
|
||||
{:emoji-id emoji-id
|
||||
:own (boolean (seq own))
|
||||
:emoji-reaction-id (:emoji-reaction-id (second own))
|
||||
:quantity (count reactions)}))
|
||||
acc))
|
||||
[]
|
||||
reactions))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/all-loaded?
|
||||
|
|
|
@ -99,7 +99,7 @@
|
|||
(reg-root-key-sub :chat/inputs-with-mentions :chat/inputs-with-mentions)
|
||||
(reg-root-key-sub :chats-home-list :chats-home-list)
|
||||
(reg-root-key-sub :chats/recording? :chats/recording?)
|
||||
(reg-root-key-sub :chat/reactions-authors :chat/reactions-authors)
|
||||
(reg-root-key-sub :reactions/authors :reactions/authors)
|
||||
|
||||
;;chat images lightbox
|
||||
(reg-root-key-sub :lightbox/exit-signal :lightbox/exit-signal)
|
||||
|
|
Loading…
Reference in New Issue