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) (when (or first-request cursor)
(merge (merge
{:db (assoc-in db [:pagination-info chat-id :loading-messages?] true)} {: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 (data-store.messages/messages-by-chat-id-rpc
chat-id chat-id
cursor 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.composer.link-preview.events :as link-preview]
status-im2.contexts.chat.effects status-im2.contexts.chat.effects
status-im2.contexts.chat.lightbox.events 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-for-me.events :as delete-for-me]
[status-im2.contexts.chat.messages.delete-message.events :as delete-message] [status-im2.contexts.chat.messages.delete-message.events :as delete-message]
[status-im2.contexts.chat.messages.list.state :as chat.state] [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 (:require
[quo.core :as quo] [quo.core :as quo]
[quo.theme :as quo.theme] [quo.theme :as quo.theme]
[react-native.core :as rn]
[status-im2.constants :as constants] [status-im2.constants :as constants]
[status-im2.contexts.chat.messages.drawers.view :as drawers] [status-im2.contexts.chat.messages.drawers.view :as drawers]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
@ -17,23 +18,21 @@
(defn- on-long-press (defn- on-long-press
[{:keys [message-id emoji-id user-message-content reactions-order theme]}] [{:keys [message-id emoji-id user-message-content reactions-order theme]}]
(rf/dispatch (rf/dispatch
[:chat.ui/emoji-reactions-by-message-id [:reactions/get-authors-by-message-id
{:message-id message-id {:message-id message-id
:on-success (fn [response] :on-success (fn [response]
(rf/dispatch [:chat/save-emoji-reaction-details (rf/dispatch [:reactions/save-authors
{:reaction-authors-list response {:reaction-authors-list response
:selected-reaction emoji-id}]) :selected-reaction emoji-id}])
(rf/dispatch [:dismiss-keyboard]) (rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:show-bottom-sheet (rf/dispatch [:show-bottom-sheet
{:on-close (fn [] {:on-close #(rf/dispatch
(rf/dispatch [:reactions/clear-authors])
[:chat/clear-emoji-reaction-author-details])) :content (fn []
:content (fn [] [drawers/reaction-authors
[drawers/reaction-authors {:reactions-order reactions-order
{:reactions-order reactions-order :theme theme}])
:theme theme}]) :selected-item (fn [] user-message-content)
:selected-item (fn []
user-message-content)
:padding-bottom-override 0}]))}])) :padding-bottom-override 0}]))}]))
(defn- on-press-add (defn- on-press-add
@ -56,7 +55,7 @@
(defn- view-internal (defn- view-internal
[{:keys [message-id chat-id pinned-by theme]} user-message-content] [{:keys [message-id chat-id pinned-by theme]} user-message-content]
(let [reactions (rf/sub [:chats/message-reactions message-id chat-id])] (let [reactions (rf/sub [:chats/message-reactions message-id chat-id])]
[:<> [rn/view {:border-color :red :border-width 1}
(when (seq reactions) (when (seq reactions)
[quo/react [quo/react
{:container-style {:margin-left 44 {:container-style {:margin-left 44

View File

@ -71,7 +71,7 @@
(defn reaction-authors (defn reaction-authors
[{:keys [reactions-order theme]}] [{:keys [reactions-order theme]}]
(let [{:keys [reaction-authors-list (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 selected-tab (reagent/atom (or selected-reaction
(first (keys reaction-authors-list))))] (first (keys reaction-authors-list))))]
(fn [] (fn []

View File

@ -4,12 +4,10 @@
[clojure.string :as string] [clojure.string :as string]
[status-im.browser.core :as browser] [status-im.browser.core :as browser]
[status-im.chat.models.message :as models.message] [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.communities.core :as models.communities]
[status-im.data-store.activities :as data-store.activities] [status-im.data-store.activities :as data-store.activities]
[status-im.data-store.chats :as data-store.chats] [status-im.data-store.chats :as data-store.chats]
[status-im.data-store.invitations :as data-store.invitations] [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.group-chats.core :as models.group]
[status-im.multiaccounts.update.core :as update.core] [status-im.multiaccounts.update.core :as update.core]
[status-im.pairing.core :as models.pairing] [status-im.pairing.core :as models.pairing]
@ -18,6 +16,7 @@
[status-im.wallet.core :as wallet] [status-im.wallet.core :as wallet]
[status-im2.constants :as constants] [status-im2.constants :as constants]
[status-im2.contexts.chat.events :as chat.events] [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.chat.messages.pin.events :as messages.pin]
[status-im2.contexts.contacts.events :as models.contact] [status-im2.contexts.contacts.events :as models.contact]
[status-im2.contexts.shell.activity-center.events :as activity-center] [status-im2.contexts.shell.activity-center.events :as activity-center]
@ -139,7 +138,7 @@
(js-delete response-js "emojiReactions") (js-delete response-js "emojiReactions")
(rf/merge cofx (rf/merge cofx
(process-next response-js sync-handler) (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) (seq invitations)
(let [invitations (types/js->clj invitations)] (let [invitations (types/js->clj invitations)]
@ -386,21 +385,3 @@
:on-error #(do :on-error #(do
(log/warn "failed to send a message" %) (log/warn "failed to send a message" %)
(js/alert (str "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 (ns status-im2.subs.messages
(:require (:require
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[status-im.chat.models.reactions :as models.reactions]
[status-im2.constants :as constants] [status-im2.constants :as constants]
[status-im2.contexts.chat.messages.list.events :as models.message-list] [status-im2.contexts.chat.messages.list.events :as models.message-list]
[status-im2.contexts.chat.messages.resolver.message-resolver :as resolver] [status-im2.contexts.chat.messages.resolver.message-resolver :as resolver]
@ -177,9 +176,21 @@
:<- [:multiaccount/public-key] :<- [:multiaccount/public-key]
:<- [:messages/reactions] :<- [:messages/reactions]
(fn [[current-public-key reactions] [_ message-id chat-id]] (fn [[current-public-key reactions] [_ message-id chat-id]]
(models.reactions/message-reactions (let [reactions (get-in reactions [chat-id message-id])]
current-public-key (reduce
(get-in reactions [chat-id message-id])))) (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 (re-frame/reg-sub
:chats/all-loaded? :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 :chat/inputs-with-mentions :chat/inputs-with-mentions)
(reg-root-key-sub :chats-home-list :chats-home-list) (reg-root-key-sub :chats-home-list :chats-home-list)
(reg-root-key-sub :chats/recording? :chats/recording?) (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 ;;chat images lightbox
(reg-root-key-sub :lightbox/exit-signal :lightbox/exit-signal) (reg-root-key-sub :lightbox/exit-signal :lightbox/exit-signal)