move reactions events (#18150)

This commit is contained in:
flexsurfer 2023-12-11 17:50:52 +01:00 committed by GitHub
parent 761a7df06f
commit 5570181896
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 138 additions and 190 deletions

View File

@ -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

View File

@ -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 %)))}]})

View File

@ -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}]})

View File

@ -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]

View File

@ -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" %)}]}))

View File

@ -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]))
:content (fn []
[drawers/reaction-authors
{:reactions-order reactions-order
:theme theme}])
:selected-item (fn []
user-message-content)
{:on-close #(rf/dispatch
[:reactions/clear-authors])
:content (fn []
[drawers/reaction-authors
{:reactions-order reactions-order
:theme theme}])
: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

View File

@ -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 []

View File

@ -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" %)}]})

View File

@ -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?

View File

@ -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)