2016-06-30 19:00:44 +03:00
|
|
|
(ns status-im.chat.handlers.send-message
|
|
|
|
(:require [status-im.utils.handlers :refer [register-handler] :as u]
|
|
|
|
[clojure.string :as s]
|
2016-10-04 14:49:59 +03:00
|
|
|
[status-im.data-store.messages :as messages]
|
2016-09-07 20:35:04 +03:00
|
|
|
[status-im.components.status :as status]
|
2016-06-30 19:00:44 +03:00
|
|
|
[status-im.utils.random :as random]
|
|
|
|
[status-im.utils.datetime :as time]
|
2016-09-04 18:39:05 +03:00
|
|
|
[re-frame.core :refer [enrich after dispatch path]]
|
2016-06-30 19:00:44 +03:00
|
|
|
[status-im.chat.utils :as cu]
|
2016-12-02 19:13:55 +02:00
|
|
|
[status-im.constants :refer [console-chat-id
|
|
|
|
wallet-chat-id
|
|
|
|
text-content-type
|
2016-06-30 19:00:44 +03:00
|
|
|
content-type-command
|
|
|
|
content-type-command-request
|
2016-11-16 09:39:28 +02:00
|
|
|
default-number-of-messages] :as c]
|
2016-12-02 19:13:55 +02:00
|
|
|
[status-im.chat.constants :refer [input-height]]
|
2016-09-04 18:39:05 +03:00
|
|
|
[status-im.utils.datetime :as datetime]
|
|
|
|
[status-im.protocol.core :as protocol]
|
2016-10-19 15:22:05 +03:00
|
|
|
[taoensso.timbre :refer-macros [debug] :as log]
|
|
|
|
[status-im.chat.handlers.console :as console]))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
|
|
|
(defn prepare-command
|
2016-10-20 16:51:37 +03:00
|
|
|
[identity chat-id clock-value request
|
2016-11-16 09:39:28 +02:00
|
|
|
{:keys [id preview preview-string params command
|
|
|
|
to-message handler-data content-type]}]
|
2016-10-20 16:51:37 +03:00
|
|
|
(let [content (or request {:command (command :name)
|
|
|
|
:params params})]
|
2016-10-11 17:24:52 +03:00
|
|
|
{:message-id id
|
2016-06-30 19:00:44 +03:00
|
|
|
:from identity
|
|
|
|
:to chat-id
|
2016-10-04 23:58:33 +03:00
|
|
|
:timestamp (time/now-ms)
|
2016-10-11 17:24:52 +03:00
|
|
|
:content (assoc content :preview preview-string
|
2016-10-20 16:51:37 +03:00
|
|
|
:handler-data handler-data
|
|
|
|
:type (name (:type command)))
|
2016-11-16 09:39:28 +02:00
|
|
|
:content-type (or content-type
|
|
|
|
(if request
|
|
|
|
content-type-command-request
|
|
|
|
content-type-command))
|
2016-06-30 19:00:44 +03:00
|
|
|
:outgoing true
|
|
|
|
:preview preview-string
|
|
|
|
:rendered-preview preview
|
|
|
|
:to-message to-message
|
|
|
|
:type (:type command)
|
2016-10-14 17:38:02 +03:00
|
|
|
:has-handler (:has-handler command)
|
2016-12-13 13:56:00 +03:00
|
|
|
:clock-value (inc clock-value)
|
|
|
|
:show? true}))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
2016-08-24 10:29:40 +03:00
|
|
|
(register-handler :send-chat-message
|
2016-06-30 19:00:44 +03:00
|
|
|
(u/side-effect!
|
2016-12-22 15:18:09 +02:00
|
|
|
(fn [{:keys [current-chat-id current-public-key current-account-id] :as db}
|
|
|
|
[_ {:keys [chat-id] :as command-message}]]
|
|
|
|
(let [text (get-in db [:chats current-chat-id :input-text])
|
|
|
|
data {:command command-message
|
|
|
|
:message text
|
|
|
|
:chat-id (or chat-id current-chat-id)
|
|
|
|
:identity current-public-key
|
|
|
|
:address current-account-id}]
|
2016-06-30 19:00:44 +03:00
|
|
|
(dispatch [:clear-input current-chat-id])
|
|
|
|
(cond
|
2016-12-22 15:18:09 +02:00
|
|
|
command-message
|
2016-06-30 19:00:44 +03:00
|
|
|
(dispatch [::check-commands-handlers! data])
|
|
|
|
(not (s/blank? text))
|
|
|
|
(dispatch [::prepare-message data]))))))
|
|
|
|
|
2016-10-19 15:22:05 +03:00
|
|
|
(defn console-command? [chat-id command-name]
|
|
|
|
(and (= console-chat-id chat-id)
|
|
|
|
(console/commands-names (keyword command-name))))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
|
|
|
(register-handler ::check-commands-handlers!
|
|
|
|
(u/side-effect!
|
2016-12-22 15:18:09 +02:00
|
|
|
(fn [_ [_ {:keys [command message chat-id] :as params}]]
|
|
|
|
(let [{:keys [command] :as message} command]
|
|
|
|
(let [params' (assoc params :command-message message)
|
2016-10-19 15:22:05 +03:00
|
|
|
command-name (:name (:command message))]
|
2016-10-11 17:24:52 +03:00
|
|
|
(if (:sent-to-jail? message)
|
|
|
|
;; todo there could be other reasons for "long-running"
|
|
|
|
;; hanling of the command besides sendTransaction
|
2016-12-09 12:54:24 +02:00
|
|
|
(dispatch [:navigate-to-modal :confirm])
|
2016-10-19 15:22:05 +03:00
|
|
|
(cond
|
|
|
|
(console-command? chat-id command-name)
|
|
|
|
(dispatch [:invoke-console-command-handler! params'])
|
|
|
|
|
|
|
|
(:has-handler command)
|
2016-06-30 19:00:44 +03:00
|
|
|
(dispatch [::invoke-command-handlers! params'])
|
2016-10-19 15:22:05 +03:00
|
|
|
|
|
|
|
:else
|
2016-11-01 19:00:26 +03:00
|
|
|
(dispatch [:prepare-command! chat-id params'])))))
|
2017-01-23 13:09:15 +03:00
|
|
|
(dispatch [:set-chat-ui-props :sending-disabled? false])
|
2016-06-30 19:00:44 +03:00
|
|
|
(when-not (s/blank? message)
|
|
|
|
(dispatch [::prepare-message params])))))
|
|
|
|
|
|
|
|
(register-handler :clear-input
|
|
|
|
(path :chats)
|
|
|
|
(fn [db [_ chat-id]]
|
|
|
|
(assoc-in db [chat-id :input-text] nil)))
|
|
|
|
|
|
|
|
(register-handler :prepare-command!
|
|
|
|
(u/side-effect!
|
2016-12-13 13:56:00 +03:00
|
|
|
(fn [{:keys [current-public-key network-status] :as db}
|
2016-12-22 15:18:09 +02:00
|
|
|
[_ add-to-chat-id {:keys [chat-id command-message command handler-data] :as params}]]
|
2017-01-20 15:54:33 +03:00
|
|
|
(let [clock-value (messages/get-last-clock-value chat-id)
|
|
|
|
request (:request (:handler-data command))
|
|
|
|
hidden-params (->> (:params (:command command))
|
|
|
|
(filter #(= (:hidden %) true))
|
|
|
|
(map #(:name %)))
|
|
|
|
command' (->> (assoc command-message :handler-data handler-data)
|
|
|
|
(prepare-command current-public-key chat-id clock-value request)
|
|
|
|
(cu/check-author-direction db chat-id))]
|
2016-12-22 15:18:09 +02:00
|
|
|
(log/debug "Handler data: " request handler-data (dissoc params :commands :command-message))
|
2016-12-13 13:56:00 +03:00
|
|
|
(dispatch [:update-message-overhead! chat-id network-status])
|
2017-01-23 13:09:15 +03:00
|
|
|
(dispatch [:set-chat-ui-props :sending-disabled? false])
|
2017-01-20 15:54:33 +03:00
|
|
|
(dispatch [::send-command! add-to-chat-id (assoc params :command command') hidden-params])
|
2016-11-02 15:20:50 +08:00
|
|
|
(when (cu/console? chat-id)
|
2016-12-22 15:18:09 +02:00
|
|
|
(dispatch `[:console-respond-command params]))
|
|
|
|
(when (and (= "send" (get-in command-message [:command :name]))
|
2016-11-01 19:00:26 +03:00
|
|
|
(not= add-to-chat-id wallet-chat-id))
|
2016-12-22 15:18:09 +02:00
|
|
|
(let [ct (if request
|
|
|
|
c/content-type-wallet-request
|
|
|
|
c/content-type-wallet-command)
|
|
|
|
command-message' (assoc command-message :id (random/id)
|
|
|
|
:content-type ct)
|
|
|
|
params' (assoc params :command-message command-message')]
|
2016-11-01 19:00:26 +03:00
|
|
|
(dispatch [:prepare-command! wallet-chat-id params'])))))))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
|
|
|
(register-handler ::send-command!
|
|
|
|
(u/side-effect!
|
2017-01-20 15:54:33 +03:00
|
|
|
(fn [_ [_ add-to-chat-id params hidden-params]]
|
2016-11-01 19:00:26 +03:00
|
|
|
(dispatch [::add-command add-to-chat-id params])
|
2017-01-20 15:54:33 +03:00
|
|
|
(dispatch [::save-command! add-to-chat-id params hidden-params])
|
2016-11-01 19:00:26 +03:00
|
|
|
(when (not= add-to-chat-id wallet-chat-id)
|
|
|
|
(dispatch [::dispatch-responded-requests! params])
|
|
|
|
(dispatch [::send-command-protocol! params])))))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
|
|
|
(register-handler ::add-command
|
2016-11-01 19:00:26 +03:00
|
|
|
(after (fn [_ [_ _ {:keys [handler]}]]
|
2016-06-30 19:00:44 +03:00
|
|
|
(when handler (handler))))
|
2016-11-01 19:00:26 +03:00
|
|
|
(fn [db [_ add-to-chat-id {:keys [chat-id command]}]]
|
|
|
|
(cu/add-message-to-db db add-to-chat-id chat-id command)))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
|
|
|
(register-handler ::save-command!
|
|
|
|
(u/side-effect!
|
2017-01-20 15:54:33 +03:00
|
|
|
(fn [_ [_ chat-id {:keys [command]} hidden-params]]
|
|
|
|
(let [command (-> command
|
|
|
|
(update-in [:content :params] #(apply dissoc % hidden-params))
|
|
|
|
(dissoc :rendered-preview :to-message :has-handler))]
|
|
|
|
(messages/save chat-id command)))))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
|
|
|
(register-handler ::dispatch-responded-requests!
|
|
|
|
(u/side-effect!
|
|
|
|
(fn [_ [_ {:keys [command chat-id]}]]
|
|
|
|
(let [{:keys [to-message]} command]
|
|
|
|
(when to-message
|
|
|
|
(dispatch [:request-answered! chat-id to-message]))))))
|
|
|
|
|
|
|
|
(register-handler ::invoke-command-handlers!
|
|
|
|
(u/side-effect!
|
2016-12-22 15:18:09 +02:00
|
|
|
(fn [db [_ {:keys [chat-id address command-message]
|
2016-10-11 17:24:52 +03:00
|
|
|
:as parameters}]]
|
2016-12-22 15:18:09 +02:00
|
|
|
(let [{:keys [id command params]} command-message
|
2016-06-30 19:00:44 +03:00
|
|
|
{:keys [type name]} command
|
2016-10-06 16:15:57 +03:00
|
|
|
path [(if (= :command type) :commands :responses)
|
|
|
|
name
|
|
|
|
:handler]
|
|
|
|
to (get-in db [:contacts chat-id :address])
|
|
|
|
params {:parameters params
|
2016-10-11 17:24:52 +03:00
|
|
|
:context {:from address
|
|
|
|
:to to
|
|
|
|
:message-id id}}]
|
|
|
|
(status/call-jail
|
|
|
|
chat-id
|
|
|
|
path
|
|
|
|
params
|
|
|
|
#(dispatch [:command-handler! chat-id parameters %]))))))
|
|
|
|
|
2016-06-30 19:00:44 +03:00
|
|
|
(register-handler ::prepare-message
|
|
|
|
(u/side-effect!
|
2016-12-21 12:44:42 +03:00
|
|
|
(fn [{:keys [network-status] :as db} [_ {:keys [chat-id identity message] :as params}]]
|
2016-12-13 13:56:00 +03:00
|
|
|
(let [{:keys [group-chat]} (get-in db [:chats chat-id])
|
|
|
|
clock-value (messages/get-last-clock-value chat-id)
|
|
|
|
message' (cu/check-author-direction
|
2016-12-22 15:18:09 +02:00
|
|
|
db chat-id
|
|
|
|
{:message-id (random/id)
|
|
|
|
:chat-id chat-id
|
|
|
|
:content message
|
|
|
|
:from identity
|
|
|
|
:content-type text-content-type
|
|
|
|
:outgoing true
|
|
|
|
:timestamp (time/now-ms)
|
|
|
|
:clock-value (inc clock-value)
|
|
|
|
:show? true})
|
2016-12-13 13:56:00 +03:00
|
|
|
message'' (if group-chat
|
|
|
|
(assoc message' :group-id chat-id :message-type :group-user-message)
|
|
|
|
(assoc message' :to chat-id :message-type :user-message))
|
|
|
|
params' (assoc params :message message'')]
|
|
|
|
(dispatch [:update-message-overhead! chat-id network-status])
|
2017-01-23 13:09:15 +03:00
|
|
|
(dispatch [:set-chat-ui-props :sending-disabled? false])
|
2016-06-30 19:00:44 +03:00
|
|
|
(dispatch [::add-message params'])
|
2016-08-24 16:40:36 +03:00
|
|
|
(dispatch [::save-message! params'])))))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
|
|
|
(register-handler ::add-message
|
|
|
|
(fn [db [_ {:keys [chat-id message]}]]
|
2016-11-01 19:00:26 +03:00
|
|
|
(cu/add-message-to-db db chat-id chat-id message)))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
|
|
|
(register-handler ::save-message!
|
2016-08-24 16:40:36 +03:00
|
|
|
(after (fn [_ [_ params]]
|
|
|
|
(dispatch [::send-message! params])))
|
2016-06-30 19:00:44 +03:00
|
|
|
(u/side-effect!
|
|
|
|
(fn [_ [_ {:keys [chat-id message]}]]
|
2017-01-16 14:39:46 +02:00
|
|
|
(dispatch [:upsert-chat! {:chat-id chat-id
|
|
|
|
:timestamp (time/now-ms)}])
|
2016-10-04 14:49:59 +03:00
|
|
|
(messages/save chat-id message))))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
2016-12-02 19:13:55 +02:00
|
|
|
(register-handler :clear-response-suggestions
|
|
|
|
(fn [db [_ chat-id]]
|
|
|
|
(-> db
|
|
|
|
(update-in [:suggestions] dissoc chat-id)
|
|
|
|
(update-in [:has-suggestions?] dissoc chat-id)
|
2016-12-22 15:18:09 +02:00
|
|
|
(assoc-in [:animations :to-response-height chat-id] input-height))))
|
2016-12-02 19:13:55 +02:00
|
|
|
|
|
|
|
(register-handler ::send-dapp-message
|
|
|
|
(u/side-effect!
|
2016-12-27 17:16:53 +02:00
|
|
|
(fn [db [_ chat-id {:keys [content]}]]
|
2016-12-02 19:13:55 +02:00
|
|
|
(let [data (get-in db [:local-storage chat-id])
|
|
|
|
path [:functions
|
|
|
|
:message-handler]
|
|
|
|
params {:parameters {:message content}
|
|
|
|
:context {:data data}}]
|
|
|
|
(dispatch [:clear-response-suggestions chat-id])
|
|
|
|
(status/call-jail chat-id
|
|
|
|
path
|
|
|
|
params
|
|
|
|
(fn [{:keys [result]}]
|
|
|
|
(log/debug "Message handler result: " result)
|
|
|
|
(dispatch [::received-dapp-message chat-id result])))))))
|
|
|
|
|
|
|
|
(register-handler ::received-dapp-message
|
|
|
|
(u/side-effect!
|
2016-12-27 17:16:53 +02:00
|
|
|
(fn [_ [_ chat-id {:keys [returned]}]]
|
2016-12-02 19:13:55 +02:00
|
|
|
(let [{:keys [data messages err]} returned
|
2016-12-27 19:45:54 +02:00
|
|
|
content (or err data)]
|
2016-12-02 19:13:55 +02:00
|
|
|
(doseq [message messages]
|
|
|
|
(let [{:keys [message type]} message]
|
|
|
|
(dispatch [:received-message
|
|
|
|
{:message-id (random/id)
|
|
|
|
:content (str type ": " message)
|
|
|
|
:content-type text-content-type
|
|
|
|
:outgoing false
|
|
|
|
:chat-id chat-id
|
|
|
|
:from chat-id
|
|
|
|
:to "me"}])))
|
|
|
|
(when content
|
|
|
|
(dispatch [:received-message
|
|
|
|
{:message-id (random/id)
|
|
|
|
:content (str content)
|
|
|
|
:content-type text-content-type
|
|
|
|
:outgoing false
|
|
|
|
:chat-id chat-id
|
|
|
|
:from chat-id
|
|
|
|
:to "me"}]))))))
|
|
|
|
|
2016-06-30 19:00:44 +03:00
|
|
|
(register-handler ::send-message!
|
|
|
|
(u/side-effect!
|
2016-12-22 15:18:09 +02:00
|
|
|
(fn [{:keys [web3 chats network-status]
|
|
|
|
:as db} [_ {{:keys [message-type]
|
|
|
|
:as message} :message
|
|
|
|
chat-id :chat-id}]]
|
2016-12-27 17:16:53 +02:00
|
|
|
(let [{:keys [dapp?]} (get-in db [:contacts chat-id])]
|
2016-12-02 19:13:55 +02:00
|
|
|
(if dapp?
|
|
|
|
(dispatch [::send-dapp-message chat-id message])
|
|
|
|
(when message
|
|
|
|
(let [message' (select-keys message [:from :message-id])
|
2016-12-13 13:56:00 +03:00
|
|
|
payload (select-keys message [:timestamp :content :content-type
|
|
|
|
:clock-value :show?])
|
|
|
|
payload (if (= network-status :offline)
|
|
|
|
(assoc payload :show? false)
|
|
|
|
payload)
|
2016-12-02 19:13:55 +02:00
|
|
|
options {:web3 web3
|
|
|
|
:message (assoc message' :payload payload)}]
|
|
|
|
(if (= 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})))
|
|
|
|
(protocol/send-message! (assoc-in options
|
2016-12-13 13:56:00 +03:00
|
|
|
[:message :to] (:to message)))))))))))
|
2016-06-30 19:00:44 +03:00
|
|
|
|
|
|
|
(register-handler ::send-command-protocol!
|
|
|
|
(u/side-effect!
|
2016-12-13 13:56:00 +03:00
|
|
|
(fn [{:keys [web3 current-public-key chats network-status] :as db}
|
2016-10-20 16:51:37 +03:00
|
|
|
[_ {:keys [chat-id command]}]]
|
|
|
|
(log/debug "sending command: " command)
|
|
|
|
(when (cu/not-console? chat-id)
|
|
|
|
(let [{:keys [public-key private-key]} (chats chat-id)
|
|
|
|
{:keys [group-chat]} (get-in db [:chats chat-id])
|
|
|
|
|
|
|
|
payload (-> command
|
2016-12-13 13:56:00 +03:00
|
|
|
(select-keys [:content :content-type
|
|
|
|
:clock-value :show?])
|
2016-10-20 16:51:37 +03:00
|
|
|
(assoc :timestamp (datetime/now-ms)))
|
2016-12-13 13:56:00 +03:00
|
|
|
payload (if (= network-status :offline)
|
|
|
|
(assoc payload :show? false)
|
|
|
|
payload)
|
2016-10-20 16:51:37 +03:00
|
|
|
options {:web3 web3
|
|
|
|
:message {:from current-public-key
|
|
|
|
:message-id (:message-id command)
|
|
|
|
:payload payload}}]
|
|
|
|
(if group-chat
|
|
|
|
(protocol/send-group-message! (assoc options
|
|
|
|
:group-id chat-id
|
|
|
|
:keypair {:public public-key
|
|
|
|
:private private-key}))
|
|
|
|
(protocol/send-message! (assoc-in options
|
2016-12-13 13:56:00 +03:00
|
|
|
[:message :to] chat-id))))))))
|