Send message refactoring

This commit is contained in:
janherich 2017-12-27 19:23:58 +01:00 committed by Andrey Shovkoplyas
parent e580b6e96f
commit 77b966c864
3 changed files with 116 additions and 108 deletions

View File

@ -8,6 +8,7 @@
[status-im.chat.models.input :as input-model]
[status-im.chat.events.commands :as commands-events]
[status-im.chat.events.animation :as animation-events]
[status-im.chat.events.send-message :as send-message-events]
[status-im.bots.events :as bots-events]
[status-im.ui.components.react :as react-comp]
[status-im.utils.datetime :as time]
@ -440,8 +441,11 @@
(handlers/register-handler-fx
:send-current-message
[(re-frame/inject-cofx :random-id)]
(fn [{{:keys [current-chat-id current-public-key] :as db} :db message-id :random-id current-time :now} _]
[(re-frame/inject-cofx :random-id)
(re-frame/inject-cofx :get-last-clock-value)
(re-frame/inject-cofx :get-stored-chat)]
(fn [{{:keys [current-chat-id current-public-key] :as db} :db message-id :random-id current-time :now
:as cofx} _]
(let [input-text (get-in db [:chats current-chat-id :input-text])
chat-command (-> (input-model/selected-chat-command db)
(as-> selected-command
@ -464,14 +468,13 @@
;; no command detected, when not empty, proceed by sending text message without command processing
(if (str/blank? input-text)
{:db db}
{:db (-> db
(set-chat-input-metadata nil)
(set-chat-input-text nil))
;; TODO: refactor send-message.cljs to use atomic pure handlers and get rid of this dispatch
:dispatch [:prepare-message {:message input-text
:chat-id current-chat-id
:identity current-public-key
:address (:accounts/current-account-id db)}]})))))
(send-message-events/prepare-message (assoc cofx :db (-> db
(set-chat-input-metadata nil)
(set-chat-input-text nil)))
{:message-text input-text
:chat-id current-chat-id
:identity current-public-key
:address (:accounts/current-account-id db)}))))))
;; TODO: remove this handler and leave only helper fn once all invocations are refactored
(handlers/register-handler-db

View File

@ -0,0 +1,103 @@
(ns status-im.chat.events.send-message
(:require [re-frame.core :as re-frame]
[status-im.utils.handlers :as handlers]
[status-im.constants :as constants]
[status-im.utils.clocks :as clocks]
[status-im.utils.config :as config]
[status-im.chat.models :as chat.models]
[status-im.chat.utils :as chat.utils]
[status-im.protocol.core :as protocol]
[status-im.native-module.core :as status]
[taoensso.timbre :as log]))
(re-frame/reg-fx
::send-notification
(fn [fcm-token]
(log/debug "send-notification fcm-token: " fcm-token)
(status/notify fcm-token #(log/debug "send-notification cb result: " %))))
(re-frame/reg-fx
::send-message
(fn [message]
(protocol/send-message! message)))
(re-frame/reg-fx
::send-group-message
(fn [message]
(protocol/send-group-message! message)))
(re-frame/reg-fx
::send-public-group-message
(fn [message]
(protocol/send-public-group-message! message)))
(defn- send-message
[{:keys [web3 network-status local-storage chats]
:contacts/keys [contacts]
:as db}
{:keys [message-type content from chat-id to] :as message}]
(let [{:keys [dapp? fcm-token]} (get contacts chat-id)
{:keys [public-key private-key]} (get chats chat-id)
sender-name (get-in contacts [from :name])]
;; whenever we are sending message to DApp, we are assuming it's a status bot,
;; so we are just calling jail `on-message-send` function
(when message
(if dapp?
{:call-jail-function {:chat-id chat-id
:function :on-message-send
:parameters {:message content}
:content {:data (get local-storage chat-id)
:from from}}}
(let [payload (select-keys message [:timestamp :content :content-type
:clock-value :show?])
message-to-send {:web3 web3
:message (-> (select-keys message [:message-id :from])
(assoc :payload (if (= :offline network-status)
(assoc payload :show? false)
payload)))}]
(case message-type
:group-user-message {::send-group-message
(assoc message-to-send
:group-id chat-id
:keypair {:public public-key
:private private-key})}
:public-group-user-message {::send-public-group-message
(assoc message-to-send
:group-id chat-id
:username sender-name)}
:user-message (cond-> {::send-message
(assoc-in message-to-send
[:message :to] to)}
(and fcm-token config/notifications-wip-enabled?)
(assoc ::send-notification fcm-token))))))))
(defn prepare-message
[{:keys [db now random-id get-last-clock-value] :as cofx}
{:keys [chat-id identity message-text] :as params}]
(let [{:keys [group-chat public?]} (get-in db [:chats chat-id])
message (cond-> {:message-id random-id
:chat-id chat-id
:content message-text
:from identity
:content-type constants/text-content-type
:outgoing true
:timestamp now
:clock-value (clocks/send (get-last-clock-value chat-id))
:show? true}
(not group-chat)
(assoc :message-type :user-message
:to chat-id)
group-chat
(assoc :group-id chat-id)
(and group-chat public?)
(assoc :message-type :public-group-user-message)
(and group-chat (not public?))
(assoc :message-type :group-user-message))]
(as-> (chat.models/upsert-chat cofx {:chat-id chat-id})
fx (merge fx
{:db (chat.utils/add-message-to-db (:db fx) chat-id chat-id message)
:save-message message
;; TODO janherich - get rid of this, there is absolutely no reason why it can't be just
;; plain app-db inc + chat update
:dispatch [:update-message-overhead! chat-id (:network-status db)]}
(send-message (:db fx) message)))))

View File

@ -166,57 +166,6 @@
(fn [res]
(dispatch [:command-handler! chat-id orig-params res])))})))))
(register-handler :prepare-message
(u/side-effect!
(fn [{:keys [network-status] :as db} [_ {:keys [chat-id identity message] :as params}]]
(let [{:keys [group-chat public?]} (get-in db [:chats chat-id])
clock-value (messages/get-last-clock-value chat-id)
message' {:message-id (random/id)
:chat-id chat-id
:content message
:from identity
:content-type text-content-type
:outgoing true
:timestamp (datetime/now-ms)
:clock-value (clocks/send clock-value)
:show? true}
message'' (cond-> message'
(and group-chat public?)
(assoc :group-id chat-id :message-type :public-group-user-message)
(and group-chat (not public?))
(assoc :group-id chat-id :message-type :group-user-message)
(not group-chat)
(assoc :to chat-id :message-type :user-message))
params' (assoc params :message message'')]
(dispatch [:update-message-overhead! chat-id network-status])
(dispatch [::add-message params'])
(dispatch [::save-message! params'])))))
(register-handler ::add-message
(fn [db [_ {:keys [chat-id message]}]]
(cu/add-message-to-db db chat-id chat-id message)))
(register-handler
::save-message!
(after (fn [_ [_ params]]
(dispatch [::send-message! params])))
(u/side-effect!
(fn [_ [_ {:keys [chat-id message]}]]
(dispatch [:upsert-chat! {:chat-id chat-id}])
(messages/save message))))
(register-handler
::send-dapp-message
(u/side-effect!
(fn [{:accounts/keys [current-account-id] :as db} [_ chat-id {:keys [content]}]]
(let [data (get-in db [:local-storage chat-id])]
(status/call-function!
{:chat-id chat-id
:function :on-message-send
:parameters {:message content}
:context {:data data
:from current-account-id}})))))
(register-handler
:received-bot-response
(u/side-effect!
@ -287,53 +236,6 @@
{:result result
:chat-id chat-id}])))))
(defn send-notification [fcm-token message]
(if (and fcm-token config/notifications-wip-enabled?)
(do (log/debug "send-notification fcm-token: " fcm-token)
(log/debug "send-notification message: " message)
(status/notify fcm-token (fn [res]
(log/debug "send-notification cb result: " res))))
(log/debug "send-notification message not sending because fcm-token is unavailable or notification flag is off")))
(register-handler ::send-message!
(u/side-effect!
(fn [{:keys [web3 chats network-status]
:accounts/keys [accounts current-account-id]
:contacts/keys [contacts]
:as db} [_ {{:keys [message-type]
:as message} :message
chat-id :chat-id}]]
(let [{:keys [dapp? fcm-token]} (get contacts chat-id)]
(if dapp?
(dispatch [::send-dapp-message chat-id message])
(when message
(let [message' (select-keys message [:from :message-id])
payload (select-keys message [:timestamp :content :content-type
:clock-value :show?])
payload (if (= network-status :offline)
(assoc payload :show? false)
payload)
options {:web3 web3
:message (assoc message' :payload payload)}]
(cond
(= message-type :group-user-message)
(let [{:keys [public-key private-key]} (chats chat-id)]
(protocol/send-group-message! (assoc options
:group-id chat-id
:keypair {:public public-key
:private private-key})))
(= message-type :public-group-user-message)
(protocol/send-public-group-message!
(let [username (get-in accounts [current-account-id :name])]
(assoc options :group-id chat-id
:username username)))
:else
(do (protocol/send-message! (assoc-in options
[:message :to] (:to message)))
(send-notification fcm-token (:message options)))))))))))
(register-handler ::send-command-protocol!
(u/side-effect!
(fn [{:keys [web3 current-public-key chats network-status]