status-react/src/status_im/chat/handlers/send_message.cljs

202 lines
7.9 KiB
Plaintext
Raw Normal View History

(ns status-im.chat.handlers.send-message
(:require [status-im.utils.handlers :refer [register-handler] :as u]
[clojure.string :as s]
[status-im.models.messages :as messages]
[status-im.components.jail :as j]
[status-im.utils.random :as random]
[status-im.utils.datetime :as time]
[re-frame.core :refer [enrich after debug dispatch path]]
[status-im.chat.suggestions :as suggestions]
[status-im.models.commands :as commands]
[status-im.chat.utils :as cu]
[status-im.constants :refer [text-content-type
content-type-command
content-type-command-request
default-number-of-messages]]
[status-im.protocol.api :as api]))
(defn default-delivery-status [chat-id]
(if (cu/console? chat-id)
:seen
:pending))
(defn prepare-message
[{:keys [identity current-chat-id] :as db} _]
(let [text (get-in db [:chats current-chat-id :input-text])
[command] (suggestions/check-suggestion db (str text " "))
message (cu/check-author-direction
db current-chat-id
{:msg-id (random/id)
:chat-id current-chat-id
:content text
:to current-chat-id
:from identity
:content-type text-content-type
:delivery-status (default-delivery-status current-chat-id)
:outgoing true
:timestamp (time/now-ms)})]
(if command
(commands/set-command-input db :commands command)
(assoc db :new-message (when-not (s/blank? text) message)))))
(defn prepare-command
[identity chat-id {:keys [preview preview-string content command to-message]}]
(let [content {:command (command :name)
:content content}]
{:msg-id (random/id)
:from identity
:to chat-id
:content (assoc content :preview preview-string)
:content-type content-type-command
:delivery-status (default-delivery-status chat-id)
:outgoing true
:preview preview-string
:rendered-preview preview
:to-message to-message
:type (:type command)
:has-handler (:has-handler command)}))
(register-handler :send-chat-msg
(u/side-effect!
(fn [{:keys [current-chat-id identity current-account-id] :as db}]
(let [staged-commands (vals (get-in db [:chats current-chat-id :staged-commands]))
text (get-in db [:chats current-chat-id :input-text])
data {:commands staged-commands
:message text
:chat-id current-chat-id
:identity identity
:address current-account-id}]
(dispatch [:clear-input current-chat-id])
(cond
(seq staged-commands)
(dispatch [::check-commands-handlers! data])
(not (s/blank? text))
(dispatch [::prepare-message data]))))))
(register-handler ::check-commands-handlers!
(u/side-effect!
(fn [_ [_ {:keys [commands message] :as params}]]
(doseq [{:keys [command] :as message} commands]
(let [params' (assoc params :command message)]
(if (:pending message)
(dispatch [:navigate-to :confirm])
(if (:has-handler command)
(dispatch [::invoke-command-handlers! params'])
(dispatch [:prepare-command! params'])))))
(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!
(fn [db [_ {:keys [chat-id command identity] :as params}]]
(let [command' (->> command
(prepare-command identity chat-id)
(cu/check-author-direction db chat-id))]
(dispatch [::clear-command chat-id (:id command)])
(dispatch [::send-command! (assoc params :command command')])))))
(register-handler ::clear-command
(fn [db [_ chat-id id]]
(update-in db [:chats chat-id :staged-commands] dissoc id)))
(register-handler ::send-command!
(u/side-effect!
(fn [_ [_ params]]
(dispatch [::add-command params])
(dispatch [::save-command! params])
(dispatch [::dispatch-responded-requests! params])
(dispatch [::send-command-protocol! params]))))
(register-handler ::add-command
(after (fn [_ [_ {:keys [handler]}]]
(when handler (handler))))
(fn [db [_ {:keys [chat-id command]}]]
(cu/add-message-to-db db chat-id command)))
(register-handler ::save-command!
(u/side-effect!
(fn [_ [_ {:keys [command chat-id]}]]
(messages/save-message
chat-id
(dissoc command :rendered-preview :to-message :has-handler)))))
(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!
(fn [db [_ {:keys [chat-id address] :as parameters}]]
(let [{:keys [command content]} (:command parameters)
{:keys [type name]} command
path [(if (= :command type) :commands :responses)
name
:handler]
to (get-in db [:contacts chat-id :address])
params {:value content
:command {:from address
:to to}}]
(j/call chat-id
path
params
#(dispatch [:command-handler! chat-id parameters %]))))))
(register-handler ::prepare-message
(u/side-effect!
(fn [db [_ {:keys [chat-id identity message] :as params}]]
(let [message' (cu/check-author-direction
db chat-id
{:msg-id (random/id)
:chat-id chat-id
:content message
:to chat-id
:from identity
:content-type text-content-type
:delivery-status (default-delivery-status chat-id)
:outgoing true
:timestamp (time/now-ms)})
params' (assoc params :message message')]
(dispatch [::add-message params'])
(dispatch [::save-message! params'])
(dispatch [::send-message! params'])))))
(register-handler ::add-message
(fn [db [_ {:keys [chat-id message]}]]
(cu/add-message-to-db db chat-id message)))
(register-handler ::save-message!
(u/side-effect!
(fn [_ [_ {:keys [chat-id message]}]]
(messages/save-message chat-id message))))
(register-handler ::send-message!
(u/side-effect!
(fn [db [_ {:keys [message chat-id]}]]
(when (and message (cu/not-console? chat-id))
(let [{:keys [group-chat]} (get-in db [:chats chat-id])
message' (select-keys message [:content :msg-id])]
(if group-chat
(api/send-group-user-msg (assoc message' :group-id chat-id))
(api/send-user-msg (assoc message' :to chat-id))))))))
(register-handler ::send-command-protocol!
(u/side-effect!
(fn [db [_ {:keys [chat-id command]}]]
(let [{:keys [content]} command]
(when (cu/not-console? chat-id)
(let [{:keys [group-chat]} (get-in db [:chats chat-id])
message {:content content
:content-type content-type-command}]
(if group-chat
(api/send-group-user-msg (assoc message :group-id chat-id))
(api/send-user-msg (assoc message :to chat-id)))))))))