diff --git a/src/status_im/chat/events/commands.cljs b/src/status_im/chat/events/commands.cljs index c512aee67e..4c6f0a0f93 100644 --- a/src/status_im/chat/events/commands.cljs +++ b/src/status_im/chat/events/commands.cljs @@ -26,7 +26,7 @@ content-command-name :content-command :keys [content-command-scope-bitmask bot scope-bitmask params type]} :content :keys [chat-id group-id jail-id] :as message} - {:keys [data-type proceed-event-creator cache-data?] :as opts}] + {:keys [data-type] :as opts}] (let [{:accounts/keys [current-account-id] :contacts/keys [contacts]} db jail-id (or bot jail-id chat-id) @@ -56,21 +56,9 @@ (handlers/register-handler-fx ::jail-command-data-response [re-frame/trim-v] - (fn [{:keys [db]} [{{:keys [returned]} :result} - {:keys [message-id chat-id]} - {:keys [data-type proceed-event-creator cache-data?]}]] - (let [existing-message (get-in db [:chats chat-id :messages message-id])] - (cond-> {} - - (and cache-data? existing-message returned) - (as-> fx - (let [updated-message (assoc-in existing-message [:content data-type] returned)] - (assoc fx - :db (assoc-in db [:chats chat-id :messages message-id] updated-message) - :update-message (select-keys updated-message [:message-id :content])))) - - proceed-event-creator - (assoc :dispatch (proceed-event-creator returned)))))) + (fn [{:keys [db]} [{{:keys [returned]} :result} {:keys [chat-id]} {:keys [proceed-event-creator]}]] + (when proceed-event-creator + {:dispatch (proceed-event-creator returned)}))) (handlers/register-handler-fx :request-command-message-data diff --git a/src/status_im/chat/events/input.cljs b/src/status_im/chat/events/input.cljs index 0ab840022f..9c2613d056 100644 --- a/src/status_im/chat/events/input.cljs +++ b/src/status_im/chat/events/input.cljs @@ -236,77 +236,50 @@ (min (count input-text)))] (merge fx (update-text-selection new-db new-selection))))))) -(defn- request-command-data - "Requests command data from jail" - [{:keys [bot-db] :contacts/keys [contacts] :as db} - {{:keys [command - metadata - args] - :as content} :content - :keys [chat-id group-id jail-id data-type event-after-creator message-id current-time]}] - (let [{:keys [dapp? dapp-url name]} (get contacts chat-id) - metadata (merge metadata - (when dapp? - {:url (i18n/get-contact-translated chat-id :dapp-url dapp-url) - :name (i18n/get-contact-translated chat-id :name name)})) - owner-id (:owner-id command) - bot-db (get bot-db owner-id) - params (merge (input-model/args->params content) - {:bot-db bot-db - :metadata metadata}) +;; function creating "message shaped" data from command, because that's what `request-command-message-data` expects +(defn- command->message + [{:keys [bot-db current-chat-id chats]} {:keys [command] :as command-params}] + (cond-> {:chat-id current-chat-id + :jail-id (:owner-id command) + :content {:command (:name command) + :type (:type command) + :scope-bitmask (:scope-bitmask command) + :params (assoc (input-model/args->params command-params) + :bot-db (get bot-db (:owner-id command)))}} + (get-in chats [current-chat-id :group-chat]) + (assoc :group-id current-chat-id))) - command-message {:command command - :params params - :to-message (:to-message-id metadata) - :created-at current-time - :id message-id - :chat-id chat-id - :jail-id (or owner-id jail-id)} - - request-data {:message-id message-id - :chat-id chat-id - :group-id group-id - :jail-id (or owner-id jail-id) - :content {:command (:name command) - :scope-bitmask (:scope-bitmask command) - :params params - :type (:type command)}}] - (commands-events/request-command-message-data db request-data - {:data-type data-type - :proceed-event-creator (partial event-after-creator - command-message)}))) - -;; TODO (janherich) request-command-data functions and event need to be refactored, they are needlessly complicated (defn proceed-command - "Proceed with command processing by setting up and executing chain of events: + "Proceed with command processing by creating command message + setting up and executing chain of events: 1. Params validation 2. Short preview fetching 3. Preview fetching" - [{:keys [current-chat-id chats] :as db} {{:keys [bot]} :command :as content} message-id current-time] - (let [params-template {:content content - :chat-id current-chat-id - :group-id (when (get-in chats [current-chat-id :group-chat]) - current-chat-id) - :jail-id (or bot current-chat-id) - :message-id message-id - :current-time current-time} - preview-params (merge params-template - {:data-type :preview - :event-after-creator (fn [command-message jail-response] - [::send-command - (assoc-in command-message [:command :preview] jail-response)])}) - short-preview-params (merge params-template - {:data-type :short-preview - :event-after-creator (fn [_ jail-response] - [::request-command-data - (assoc-in preview-params [:content :command :short-preview] jail-response)])}) - validation-params (merge params-template - {:data-type :validator - :event-after-creator (fn [_ jail-response] - [::proceed-validation - jail-response - [[::request-command-data short-preview-params]]])})] - (request-command-data db validation-params))) + [{:keys [bot-db current-chat-id chats] :as db} {:keys [command metadata] :as command-params} message-id current-time] + (let [message (command->message db command-params) + cmd-params {:command command + :params (get-in message [:content :params]) + :to-message (:to-message-id metadata) + :created-at current-time + :id message-id + :chat-id current-chat-id + :jail-id (:jail-id message)} + event-chain {:data-type :validator + :proceed-event-creator (fn [validation-response] + [::proceed-validation + validation-response + [[:request-command-message-data + message + {:data-type :short-preview + :proceed-event-creator (fn [short-preview] + [:request-command-message-data + message + {:data-type :preview + :proceed-event-creator (fn [preview] + [::send-command + (update cmd-params :command merge + {:short-preview short-preview + :preview preview})])}])}]]])}] + (commands-events/request-command-message-data db message event-chain))) ;;;; Handlers @@ -392,28 +365,22 @@ (validator params error-events-creator))] {:dispatch-n (or error-events proceed-events)}))) -(handlers/register-handler-fx - ::request-command-data - [re-frame/trim-v] - (fn [{:keys [db]} [command-params]] - (request-command-data db command-params))) - (handlers/register-handler-fx ::send-command message-model/send-interceptors - (fn [cofx [{:keys [command] :as command-message}]] - (let [{{:keys [current-public-key current-chat-id] - :accounts/keys [current-account-id] :as db} :db} cofx - fx (message-model/process-command cofx + (fn [{:keys [db] :as cofx} [{:keys [command] :as command-message}]] + (let [{:keys [current-public-key current-chat-id] :accounts/keys [current-account-id]} db + new-db (-> (model/set-chat-ui-props db {:sending-in-progress? false}) + (clear-seq-arguments) + (set-chat-input-metadata nil) + (set-chat-input-text nil))] + (merge {:db new-db} + (message-model/process-command (assoc cofx :db new-db) {:message (get-in db [:chats current-chat-id :input-text]) :command command-message :chat-id current-chat-id :identity current-public-key - :address current-account-id})] - (update fx :db #(-> % - (clear-seq-arguments) - (set-chat-input-metadata nil) - (set-chat-input-text nil)))))) + :address current-account-id}))))) (defn command-complete? [chat-command] @@ -443,8 +410,7 @@ (set-chat-input-text nil))) {:message-text input-text :chat-id current-chat-id - :identity current-public-key - :address (:accounts/current-account-id db)}))) + :identity current-public-key}))) (handlers/register-handler-fx @@ -490,15 +456,13 @@ seq-arguments (get-in chats [current-chat-id :seq-arguments]) command (-> (input-model/selected-chat-command db) (assoc :args (into [] (conj seq-arguments text))))] - (request-command-data db {:content command - :chat-id current-chat-id - :jail-id (or (get-in command [:command :bot]) current-chat-id) - :data-type :validator - :event-after-creator (fn [_ jail-response] - [::proceed-validation - jail-response - [[::update-seq-arguments current-chat-id] - [:send-current-message]]])})))) + (commands-events/request-command-message-data db (command->message db command) + {:data-type :validator + :proceed-event-creator (fn [validation-response] + [::proceed-validation + validation-response + [[::update-seq-arguments current-chat-id] + [:send-current-message]]])})))) (handlers/register-handler-db :set-chat-seq-arg-input-text diff --git a/src/status_im/chat/events/requests.cljs b/src/status_im/chat/events/requests.cljs index 8063c11f3c..ef404f40a5 100644 --- a/src/status_im/chat/events/requests.cljs +++ b/src/status_im/chat/events/requests.cljs @@ -12,7 +12,7 @@ ;; Effects (re-frame/reg-fx - :chat-requests/mark-as-answered + ::mark-as-answered (fn [{:keys [chat-id message-id]}] (requests-store/mark-as-answered chat-id message-id))) @@ -21,15 +21,15 @@ (fn [request] (requests-store/save request))) -;; Handlers +;; Functions -(handlers/register-handler-fx - :request-answered - [re-frame/trim-v] - (fn [{:keys [db]} [chat-id message-id]] - {:db (update-in db [:chats chat-id :requests] dissoc message-id) - :chat-requests/mark-as-answered {:chat-id chat-id - :message-id message-id}})) +(defn request-answered + "Takes fx, chat-id and message, updates fx with necessary data for markin request as answered" + [fx chat-id message-id] + (-> fx + (update-in [:db :chats chat-id :requests] dissoc message-id) + (assoc ::mark-as-answered {:chat-id chat-id + :message-id message-id}))) (defn add-request "Takes fx, chat-id and message, updates fx with necessary data for adding new request" diff --git a/src/status_im/chat/events/send_message.cljs b/src/status_im/chat/events/send_message.cljs index e0613a6a97..e59a734239 100644 --- a/src/status_im/chat/events/send_message.cljs +++ b/src/status_im/chat/events/send_message.cljs @@ -37,7 +37,7 @@ :chat-send-message/send-command message-model/send-interceptors (fn [cofx [add-to-chat-id params]] - (message-model/send-command cofx nil add-to-chat-id params))) + (message-model/send-command cofx add-to-chat-id params))) (handlers/register-handler-fx :chat-send-message/from-jail diff --git a/src/status_im/chat/models/message.cljs b/src/status_im/chat/models/message.cljs index 777df1bf92..2745ac29df 100644 --- a/src/status_im/chat/models/message.cljs +++ b/src/status_im/chat/models/message.cljs @@ -4,10 +4,8 @@ [status-im.chat.events.console :as console-events] [status-im.chat.events.requests :as requests-events] [status-im.chat.models :as chat-model] - [status-im.chat.models.commands :as commands-model] - [status-im.utils.datetime :as datetime-utils] - [status-im.utils.clocks :as clocks-utils] - [status-im.utils.random :as random])) + [status-im.chat.models.commands :as commands-model] + [status-im.utils.clocks :as clocks-utils])) (defn- get-current-account [{:accounts/keys [accounts current-account-id]}] @@ -102,10 +100,10 @@ [(re-frame/inject-cofx :random-id) (re-frame/inject-cofx :random-id-seq) (re-frame/inject-cofx :get-stored-chat) re-frame/trim-v]) -(defn- handle-message-from-bot [cofx {:keys [message chat-id]}] +(defn- handle-message-from-bot [{:keys [random-id] :as cofx} {:keys [message chat-id]}] (when-let [message (cond (string? message) - {:message-id (random/id) + {:message-id random-id :content (str message) :content-type constants/text-content-type :outgoing false @@ -114,7 +112,7 @@ :to "me"} (= "request" (:type message)) - {:message-id (random/id) + {:message-id random-id :content (assoc (:content message) :bot chat-id) :content-type constants/content-type-command-request :outgoing false @@ -140,38 +138,23 @@ :from current-account-id}}}))) (defn- generate-message - [{:keys [web3 current-public-key chats network-status]} - {:keys [chat-id command message] :as args}] - (if command - (let [payload (-> command - (select-keys [:content :content-type - :clock-value :show?]) - (assoc :timestamp (datetime-utils/now-ms))) - payload (if (= network-status :offline) - (assoc payload :show? false) - payload)] - {:from current-public-key - :message-id (:message-id command) - :payload payload}) - (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)] - (assoc message' :payload payload)))) + [{:keys [network-status]} chat-id message] + (assoc (select-keys message [:from :message-id]) + :payload (cond-> (select-keys message [:content :content-type :clock-value :timestamp :show?]) + (= :offline network-status) + (assoc :show? false)))) (defn send [{{:keys [web3 chats] :accounts/keys [accounts current-account-id] :contacts/keys [contacts] :as db} :db :as cofx} - {:keys [chat-id command] :as args}] + {:keys [chat-id command message] :as args}] (let [{:keys [dapp? fcm-token]} (get contacts chat-id)] (if dapp? (send-dapp-message! cofx args) (let [{:keys [group-chat public?]} (get-in db [:chats chat-id]) options {:web3 web3 - :message (generate-message db args)}] + :message (generate-message db chat-id (or command message))}] (cond (and group-chat (not public?)) (let [{:keys [public-key private-key]} (get chats chat-id)] @@ -190,16 +173,16 @@ :payload {:title "Status" :body "You have a new message"} :tokens [fcm-token]}}))))))) -(defn- prepare-message [params chat] +(defn- prepare-message [params chat now random-id] (let [{:keys [chat-id identity message-text]} params {:keys [group-chat public? last-clock-value]} chat - message {:message-id (random/id) + message {:message-id random-id :chat-id chat-id :content message-text :from identity :content-type constants/text-content-type :outgoing true - :timestamp (datetime-utils/now-ms) + :timestamp now :clock-value (clocks-utils/send last-clock-value) :show? true}] (cond-> message @@ -215,21 +198,17 @@ (not group-chat) (assoc :to chat-id :message-type :user-message)))) -(defn send-message [{{:keys [network-status] :as db} :db - :keys [now]} - {:keys [chat-id] :as params}] +(defn send-message [{:keys [db now random-id] :as cofx} {:keys [chat-id] :as params}] (let [chat (get-in db [:chats chat-id]) - message (prepare-message params chat) + message (prepare-message params chat now random-id) params' (assoc params :message message) - fx {:db (add-message-to-db db chat-id message true) - :save-message message}] - (-> (merge fx (chat-model/upsert-chat (assoc fx :now now) - {:chat-id chat-id})) - (as-> fx' - (merge fx' (send fx' params')))))) + fx (-> (chat-model/upsert-chat cofx {:chat-id chat-id}) + (update :db add-message-to-db chat-id message true) + (assoc :save-message message))] + (merge fx (send cofx params')))) (defn- prepare-command - [identity chat-id clock-value + [identity chat-id now clock-value {request-params :params request-command :command :keys [prefill prefillBotDb] @@ -255,7 +234,7 @@ {:message-id id :from identity :to chat-id - :timestamp (datetime-utils/now-ms) + :timestamp now :content content' :content-type (or content-type (if request @@ -269,8 +248,7 @@ :show? true})) (defn send-command - [{{:keys [current-public-key network-status chats] :as db} :db - :keys [now random-id-seq]} result add-to-chat-id params] + [{{:keys [current-public-key chats] :as db} :db :keys [now random-id-seq] :as cofx} add-to-chat-id params] (let [{{:keys [handler-data command] :as content} :command @@ -280,29 +258,19 @@ hidden-params (->> (:params command) (filter :hidden) (map :name)) - command' (prepare-command current-public-key chat-id last-clock-value request content) + command' (prepare-command current-public-key chat-id now last-clock-value request content) params' (assoc params :command command') - - fx {:db (-> (merge db (:db result)) - (add-message-to-db chat-id command' true)) - :save-message (-> command' - (assoc :chat-id chat-id) - (update-in [:content :params] - #(apply dissoc % hidden-params)) - (dissoc :to-message :has-handler :raw-input))}] - - (cond-> (merge fx - (chat-model/upsert-chat (assoc fx :now now) - {:chat-id chat-id}) - (dissoc result :db)) - - true - (as-> fx' - (merge fx' (send fx' params'))) + fx (-> (chat-model/upsert-chat cofx {:chat-id chat-id}) + (update :db add-message-to-db chat-id command' true) + (assoc :save-message (-> command' + (assoc :chat-id chat-id) + (update-in [:content :params] + #(apply dissoc % hidden-params)) + (dissoc :to-message :has-handler :raw-input))))] + (cond-> (merge fx (send cofx params')) (:to-message command') - (assoc :chat-requests/mark-as-answered {:chat-id chat-id - :message-id (:to-message command')}) + (requests-events/request-answered chat-id (:to-message command')) (= constants/console-chat-id chat-id) (as-> fx' @@ -313,8 +281,8 @@ (defn invoke-console-command-handler [{:keys [db] :as cofx} {:keys [chat-id command] :as command-params}] (let [fx-fn (get console-events/console-commands->fx (-> command :command :name)) - result (fx-fn cofx command)] - (send-command cofx result chat-id command-params))) + fx (fx-fn cofx command)] + (merge fx (send-command (assoc cofx :db (or (:db fx) db)) chat-id command-params)))) (defn invoke-command-handlers [{{:keys [bot-db] @@ -347,16 +315,13 @@ (defn process-command [{:keys [db] :as cofx} {:keys [command message chat-id] :as params}] (let [{:keys [command] :as content} command] - (-> {:db (chat-model/set-chat-ui-props db {:sending-in-progress? false})} + (cond + (and (= constants/console-chat-id chat-id) + (console-events/commands-names (:name command))) + (invoke-console-command-handler cofx params) - (as-> fx' - (cond - (and (= constants/console-chat-id chat-id) - (console-events/commands-names (:name command))) - (invoke-console-command-handler (merge cofx fx') params) + (:has-handler command) + (invoke-command-handlers cofx params) - (:has-handler command) - (merge fx' (invoke-command-handlers fx' params)) - - :else - (merge fx' (send-command cofx fx' chat-id params))))))) + :else + (send-command cofx chat-id params)))) diff --git a/src/status_im/chat/views/message/message.cljs b/src/status_im/chat/views/message/message.cljs index 224443131a..1edd21169a 100644 --- a/src/status_im/chat/views/message/message.cljs +++ b/src/status_im/chat/views/message/message.cljs @@ -65,11 +65,7 @@ (defview message-content-command [{:keys [content params] :as message}] - (letsubs [command [:get-command (:content-command-ref content)]] - {:component-will-mount #(when-not (:preview content) - (re-frame/dispatch [:request-command-message-data - message {:data-type :preview - :cache-data? true}]))} + (letsubs [command [:get-command (:content-command-ref content)]] (let [preview (:preview content) {:keys [type color] icon-path :icon} command] [react/view style/content-command-view diff --git a/src/status_im/chat/views/message/request_message.cljs b/src/status_im/chat/views/message/request_message.cljs index dfe7f7c48e..a2f535be7b 100644 --- a/src/status_im/chat/views/message/request_message.cljs +++ b/src/status_im/chat/views/message/request_message.cljs @@ -77,11 +77,7 @@ [{:keys [message-id content] :as message}] (letsubs [command [:get-command (:content-command-ref content)] answered? [:is-request-answered? message-id] - status-initialized? [:get :status-module-initialized?]] - {:component-will-mount #(when-not (:preview content) - (dispatch [:request-command-message-data - message {:data-type :preview - :cache-data? true}]))} + status-initialized? [:get :status-module-initialized?]] (let [{:keys [prefill prefill-bot-db prefillBotDb params preview] text-content :text} content command (if (and params command)