* Fix #1886 Completly rework the way how async handlers work Delay further processing of message till async handler returns result * Fix indent * Fix #1903
This commit is contained in:
parent
bce18bf32c
commit
805d874846
|
@ -352,26 +352,27 @@ function handleSend(params, context) {
|
|||
gasPrice: calculateGasPrice(params["bot-db"]["sliderValue"])
|
||||
};
|
||||
|
||||
|
||||
web3.eth.sendTransaction(data, function(error, hash) {
|
||||
if (error) {
|
||||
status.sendSignal("handler-data", {
|
||||
status: "failed",
|
||||
messageId: context["message-id"],
|
||||
error: error
|
||||
status.sendSignal("handler-result", {
|
||||
status: "failed",
|
||||
error: {
|
||||
markup: status.components.validationMessage(
|
||||
I18n.t('validation_tx_title'),
|
||||
I18n.t('validation_tx_failed')
|
||||
)
|
||||
},
|
||||
origParams: context["orig-params"]
|
||||
});
|
||||
} else {
|
||||
status.sendSignal("handler-data", {
|
||||
status: "sent",
|
||||
messageId: context["message-id"],
|
||||
hash: hash
|
||||
status.sendSignal("handler-result", {
|
||||
status: "success",
|
||||
hash: hash,
|
||||
origParams: context["orig-params"]
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
status: 'not-confirmed'
|
||||
};
|
||||
// async handler, so we don't return anything immediately
|
||||
}
|
||||
|
||||
function previewSend(params, context) {
|
||||
|
@ -449,36 +450,6 @@ function previewSend(params, context) {
|
|||
} else {
|
||||
markup = [firstRow];
|
||||
}
|
||||
|
||||
if (!(context["handler-data"]
|
||||
&& context["handler-data"]["status"] === "sent")) {
|
||||
var pendingRow = status.components.text(
|
||||
{
|
||||
style: {
|
||||
color: "#9199a0",
|
||||
fontSize: 12,
|
||||
lineHeight: 18
|
||||
}
|
||||
},
|
||||
I18n.t('send_transaction_pending')
|
||||
);
|
||||
markup.push(pendingRow);
|
||||
}
|
||||
|
||||
if (context["handler-data"]
|
||||
&& context["handler-data"]["status"] === "failed") {
|
||||
var errorRow = status.components.text(
|
||||
{
|
||||
style: {
|
||||
color: "red",
|
||||
fontSize: 12,
|
||||
lineHeight: 18
|
||||
}
|
||||
},
|
||||
I18n.t('send_transaction_failed')
|
||||
);
|
||||
markup.push(errorRow);
|
||||
}
|
||||
|
||||
return {
|
||||
markup: status.components.view(
|
||||
|
@ -512,6 +483,7 @@ var send = {
|
|||
params: paramsSend,
|
||||
validator: validateSend,
|
||||
handler: handleSend,
|
||||
asyncHandler: true,
|
||||
preview: previewSend,
|
||||
shortPreview: shortPreviewSend
|
||||
};
|
||||
|
|
|
@ -14,8 +14,6 @@ I18n.translations = {
|
|||
send_explanation_3: 'probably within 30 seconds.',
|
||||
send_explanation_4: 'probably within a few seconds.',
|
||||
send_sending_to: 'to ',
|
||||
send_transaction_pending: 'transaction pending',
|
||||
send_transaction_failed: 'transaction failed',
|
||||
|
||||
eth: 'ETH',
|
||||
|
||||
|
@ -25,6 +23,8 @@ I18n.translations = {
|
|||
request_requesting_from: 'from ',
|
||||
|
||||
validation_title: 'Amount',
|
||||
validation_tx_title: 'Transaction',
|
||||
validation_tx_failed: 'Transaction failed',
|
||||
validation_amount_specified: 'Amount must be specified',
|
||||
validation_invalid_number: 'Amount is not valid number',
|
||||
validation_amount_is_too_small: 'Amount is too precise. The smallest unit you can send is 1 Wei (1x10^-18 ETH)',
|
||||
|
|
|
@ -27,6 +27,7 @@ Command.prototype.create = function (com) {
|
|||
this.description = com.description;
|
||||
this.handler = com.handler;
|
||||
this["has-handler"] = com.handler != null;
|
||||
this["async-handler"] = (com.handler != null) && com.asyncHandler
|
||||
this["registered-only"] = com.registeredOnly;
|
||||
this.validator = com.validator;
|
||||
this.color = com.color;
|
||||
|
@ -41,6 +42,7 @@ Command.prototype.create = function (com) {
|
|||
this["execute-immediately?"] = com.executeImmediately;
|
||||
this["sequential-params"] = com.sequentialParams;
|
||||
this["hide-send-button"] = com.hideSendButton;
|
||||
|
||||
this.addToCatalog();
|
||||
|
||||
return this;
|
||||
|
|
|
@ -13,111 +13,110 @@
|
|||
|
||||
(defn generate-context
|
||||
"Generates context for jail call"
|
||||
[{:keys [chats handler-data] :accounts/keys [current-account-id]} message-id chat-id to group-id]
|
||||
[{:keys [chats] :accounts/keys [current-account-id]} chat-id to group-id]
|
||||
(merge {:platform platform/platform
|
||||
:from current-account-id
|
||||
:to to
|
||||
:chat {:chat-id chat-id
|
||||
:group-chat (or (get-in chats [chat-id :group-chat])
|
||||
(not (nil? group-id)))}
|
||||
:handler-data (get handler-data message-id)}
|
||||
(not (nil? group-id)))}}
|
||||
i18n/delimeters))
|
||||
|
||||
;;;; Coeffects
|
||||
|
||||
(reg-cofx
|
||||
::get-persisted-message
|
||||
(fn [coeffects _]
|
||||
(assoc coeffects :get-persisted-message msg-store/get-by-id)))
|
||||
::get-persisted-message
|
||||
(fn [coeffects _]
|
||||
(assoc coeffects :get-persisted-message msg-store/get-by-id)))
|
||||
|
||||
;;;; Effects
|
||||
|
||||
(reg-fx
|
||||
::update-persisted-message
|
||||
(fn [message]
|
||||
(msg-store/update message)))
|
||||
::update-persisted-message
|
||||
(fn [message]
|
||||
(msg-store/update message)))
|
||||
|
||||
|
||||
(reg-fx
|
||||
:chat-fx/call-jail
|
||||
(fn [{:keys [callback-events-creator] :as opts}]
|
||||
(status/call-jail
|
||||
(-> opts
|
||||
(dissoc :callback-events-creator)
|
||||
(assoc :callback
|
||||
(fn [jail-response]
|
||||
(doseq [event (callback-events-creator jail-response)]
|
||||
(dispatch event))))))))
|
||||
:chat-fx/call-jail
|
||||
(fn [{:keys [callback-events-creator] :as opts}]
|
||||
(status/call-jail
|
||||
(-> opts
|
||||
(dissoc :callback-events-creator)
|
||||
(assoc :callback
|
||||
(fn [jail-response]
|
||||
(doseq [event (callback-events-creator jail-response)]
|
||||
(dispatch event))))))))
|
||||
|
||||
;;;; Handlers
|
||||
|
||||
(register-handler-fx
|
||||
::jail-command-data-response
|
||||
[trim-v]
|
||||
(fn [{:keys [db]} [{{:keys [returned]} :result} {:keys [message-id on-requested]} data-type]]
|
||||
(cond-> {}
|
||||
returned
|
||||
(assoc :db (assoc-in db [:message-data data-type message-id] returned))
|
||||
(and returned
|
||||
(= :preview data-type))
|
||||
(assoc ::update-persisted-message {:message-id message-id
|
||||
:preview (prn-str returned)})
|
||||
on-requested
|
||||
(assoc :dispatch (on-requested returned)))))
|
||||
::jail-command-data-response
|
||||
[trim-v]
|
||||
(fn [{:keys [db]} [{{:keys [returned]} :result} {:keys [message-id on-requested]} data-type]]
|
||||
(cond-> {}
|
||||
returned
|
||||
(assoc :db (assoc-in db [:message-data data-type message-id] returned))
|
||||
(and returned
|
||||
(= :preview data-type))
|
||||
(assoc ::update-persisted-message {:message-id message-id
|
||||
:preview (prn-str returned)})
|
||||
on-requested
|
||||
(assoc :dispatch (on-requested returned)))))
|
||||
|
||||
(register-handler-fx
|
||||
:request-command-data
|
||||
[trim-v]
|
||||
(fn [{:keys [db]}
|
||||
[{{:keys [command content-command params type]} :content
|
||||
:keys [chat-id jail-id group-id message-id] :as message}
|
||||
data-type]]
|
||||
(let [{:keys [chats]
|
||||
:accounts/keys [current-account-id]
|
||||
:contacts/keys [contacts]} db
|
||||
jail-id (or jail-id chat-id)
|
||||
jail-id (if (get-in chats [jail-id :group-chat])
|
||||
(get-in chats [jail-id :command-suggestions (keyword command) :owner-id])
|
||||
jail-id)]
|
||||
(if (get-in contacts [jail-id :commands-loaded?])
|
||||
(let [path [(if (= :response (keyword type)) :responses :commands)
|
||||
(or content-command command)
|
||||
data-type]
|
||||
to (get-in contacts [chat-id :address])
|
||||
jail-params {:parameters params
|
||||
:context (generate-context db message-id chat-id to group-id)}]
|
||||
{:chat-fx/call-jail {:jail-id jail-id
|
||||
:path path
|
||||
:params jail-params
|
||||
:callback-events-creator (fn [jail-response]
|
||||
[[::jail-command-data-response
|
||||
jail-response message data-type]])}})
|
||||
{:dispatch-n [[:add-commands-loading-callback jail-id
|
||||
#(dispatch [:request-command-data message data-type])]
|
||||
[:load-commands! jail-id]]}))))
|
||||
:request-command-data
|
||||
[trim-v]
|
||||
(fn [{:keys [db]}
|
||||
[{{:keys [command content-command params type]} :content
|
||||
:keys [chat-id jail-id group-id message-id handler-data] :as message}
|
||||
data-type]]
|
||||
(let [{:keys [chats]
|
||||
:accounts/keys [current-account-id]
|
||||
:contacts/keys [contacts]} db
|
||||
jail-id (or jail-id chat-id)
|
||||
jail-id (if (get-in chats [jail-id :group-chat])
|
||||
(get-in chats [jail-id :command-suggestions (keyword command) :owner-id])
|
||||
jail-id)]
|
||||
(if (get-in contacts [jail-id :commands-loaded?])
|
||||
(let [path [(if (= :response (keyword type)) :responses :commands)
|
||||
(or content-command command)
|
||||
data-type]
|
||||
to (get-in contacts [chat-id :address])
|
||||
jail-params {:parameters params
|
||||
:context (generate-context db chat-id to group-id)}]
|
||||
{:chat-fx/call-jail {:jail-id jail-id
|
||||
:path path
|
||||
:params jail-params
|
||||
:callback-events-creator (fn [jail-response]
|
||||
[[::jail-command-data-response
|
||||
jail-response message data-type]])}})
|
||||
{:dispatch-n [[:add-commands-loading-callback jail-id
|
||||
#(dispatch [:request-command-data message data-type])]
|
||||
[:load-commands! jail-id]]}))))
|
||||
|
||||
(register-handler-fx
|
||||
:execute-command-immediately
|
||||
[trim-v]
|
||||
(fn [_ [{command-name :name :as command}]]
|
||||
(case (keyword command-name)
|
||||
:grant-permissions
|
||||
{:dispatch [:request-permissions
|
||||
[:read-external-storage]
|
||||
#(dispatch [:initialize-geth])]}
|
||||
(log/debug "ignoring command: " command))))
|
||||
:execute-command-immediately
|
||||
[trim-v]
|
||||
(fn [_ [{command-name :name :as command}]]
|
||||
(case (keyword command-name)
|
||||
:grant-permissions
|
||||
{:dispatch [:request-permissions
|
||||
[:read-external-storage]
|
||||
#(dispatch [:initialize-geth])]}
|
||||
(log/debug "ignoring command: " command))))
|
||||
|
||||
(register-handler-fx
|
||||
:request-command-preview
|
||||
[trim-v (inject-cofx ::get-persisted-message)]
|
||||
(fn [{:keys [db get-persisted-message]} [{:keys [message-id] :as message}]]
|
||||
(let [previews (get-in db [:message-data :preview])]
|
||||
(when-not (contains? previews message-id)
|
||||
(let [{serialized-preview :preview} (get-persisted-message message-id)]
|
||||
;; if preview is already cached in db, do not request it from jail
|
||||
;; and write it directly to message-data path
|
||||
(if serialized-preview
|
||||
{:db (assoc-in db
|
||||
[:message-data :preview message-id]
|
||||
(reader/read-string serialized-preview))}
|
||||
{:dispatch [:request-command-data message :preview]}))))))
|
||||
:request-command-preview
|
||||
[trim-v (inject-cofx ::get-persisted-message)]
|
||||
(fn [{:keys [db get-persisted-message]} [{:keys [message-id] :as message}]]
|
||||
(let [previews (get-in db [:message-data :preview])]
|
||||
(when-not (contains? previews message-id)
|
||||
(let [{serialized-preview :preview} (get-persisted-message message-id)]
|
||||
;; if preview is already cached in db, do not request it from jail
|
||||
;; and write it directly to message-data path
|
||||
(if serialized-preview
|
||||
{:db (assoc-in db
|
||||
[:message-data :preview message-id]
|
||||
(reader/read-string serialized-preview))}
|
||||
{:dispatch [:request-command-data message :preview]}))))))
|
||||
|
|
|
@ -107,20 +107,9 @@
|
|||
params' (assoc params :command content')]
|
||||
(dispatch [:prepare-command! wallet-chat-id params'])))))))
|
||||
|
||||
(register-handler ::check-preview-refetch
|
||||
(fn [db [_ chat-id {:keys [message-id] :as message}]]
|
||||
(let [handler-data (get-in db [:handler-data message-id])]
|
||||
(if (:fetch-preview handler-data)
|
||||
(do (dispatch [:request-command-data (assoc message :jail-id chat-id) :preview])
|
||||
(handler-data/save-data {:message-id message-id
|
||||
:data (dissoc handler-data :fetch-preview)})
|
||||
(update-in db [:handler-data message-id] dissoc :fetch-preview))
|
||||
db))))
|
||||
|
||||
(register-handler ::send-command!
|
||||
(u/side-effect!
|
||||
(fn [_ [_ add-to-chat-id params hidden-params]]
|
||||
(dispatch [::check-preview-refetch add-to-chat-id (:command params)])
|
||||
(fn [_ [_ add-to-chat-id params hidden-params]]
|
||||
(dispatch [::add-command add-to-chat-id params])
|
||||
(dispatch [::save-command! add-to-chat-id params hidden-params])
|
||||
(when (not= add-to-chat-id wallet-chat-id)
|
||||
|
@ -163,11 +152,15 @@
|
|||
to (get-in contacts [chat-id :address])
|
||||
identity (or owner-id bot chat-id)
|
||||
bot-db (get bot-db (or bot chat-id))
|
||||
;; TODO what's actually semantic difference between `:parameters` and `:context`
|
||||
;; and do we have some clear API for both ? seems very messy and unorganized now
|
||||
jail-params {:parameters params
|
||||
:context {:from address
|
||||
:to to
|
||||
:current-account (get accounts current-account-id)
|
||||
:message-id id}}]
|
||||
:context (cond-> {:from address
|
||||
:to to
|
||||
:current-account (get accounts current-account-id)
|
||||
:message-id id}
|
||||
(:async-handler command)
|
||||
(assoc :orig-params orig-params))}]
|
||||
(dispatch
|
||||
[:check-and-load-commands!
|
||||
identity
|
||||
|
@ -175,8 +168,11 @@
|
|||
{:jail-id identity
|
||||
:path [handler-type name :handler]
|
||||
:params jail-params
|
||||
:callback (fn [res]
|
||||
(dispatch [:command-handler! chat-id orig-params res]))})])))))
|
||||
:callback (if (:async-handler command) ; async handler, we ignore return value
|
||||
(fn [_]
|
||||
(log/debug "Async command handler called"))
|
||||
(fn [res]
|
||||
(dispatch [:command-handler! chat-id orig-params res])))})])))))
|
||||
|
||||
(register-handler :prepare-message
|
||||
(u/side-effect!
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
(ns status-im.commands.events.jail
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.data-store.handler-data :as handler-data]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:save-handler-data
|
||||
(fn [data]
|
||||
(handler-data/save-data data)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:set-handler-data
|
||||
[re-frame/trim-v]
|
||||
(fn [{:keys [db]} [chat-id {:keys [messageId] :as data}]]
|
||||
(let [;; this is very bad, we should refactor our db ASAP
|
||||
message (->> (get-in db [:chats chat-id :messages])
|
||||
(filter #(= (:message-id %) messageId))
|
||||
first)
|
||||
handler-data (cond-> (dissoc data :messageId)
|
||||
;; message not there yet, indicate we want to re-fetch preview once it lands there
|
||||
(nil? message)
|
||||
(assoc :fetch-preview true))
|
||||
old-handler-data (get-in db [:handler-data messageId] {})
|
||||
new-handler-data (merge old-handler-data handler-data)]
|
||||
(cond-> {:db (assoc-in db [:handler-data messageId] new-handler-data)
|
||||
:save-handler-data {:message-id messageId
|
||||
:data new-handler-data}}
|
||||
;; message was already added to db, we can re-fetch preview
|
||||
(not (nil? message))
|
||||
(assoc :dispatch [:request-command-data (assoc message :jail-id chat-id) :preview])))))
|
|
@ -10,14 +10,13 @@
|
|||
[status-im.constants :refer [console-chat-id]]
|
||||
[status-im.i18n :refer [get-contact-translated]]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.data-store.local-storage :as local-storage]
|
||||
status-im.commands.events.jail))
|
||||
[status-im.data-store.local-storage :as local-storage]))
|
||||
|
||||
(defn command-handler!
|
||||
[_ [chat-id
|
||||
{:keys [command] :as params}
|
||||
{:keys [result error]}]]
|
||||
(let [{:keys [context returned]} result
|
||||
(let [{:keys [returned]} result
|
||||
{handler-error :error} returned]
|
||||
(cond
|
||||
handler-error
|
||||
|
@ -26,10 +25,8 @@
|
|||
|
||||
result
|
||||
(let [command' (assoc command :handler-data returned)
|
||||
params' (assoc params :command command')]
|
||||
(if (:eth_sendTransaction context)
|
||||
(dispatch [:wait-for-transaction (:id command) params'])
|
||||
(dispatch [:prepare-command! chat-id params'])))
|
||||
params' (assoc params :command command')]
|
||||
(dispatch [:prepare-command! chat-id params']))
|
||||
|
||||
(not (or error handler-error))
|
||||
(dispatch [:prepare-command! chat-id params])
|
||||
|
|
|
@ -219,7 +219,10 @@
|
|||
:markup data}])
|
||||
"send-message" (dispatch [:send-message-from-jail {:chat-id chat_id
|
||||
:message data}])
|
||||
"handler-data" (dispatch [:set-handler-data chat_id data])
|
||||
"handler-result" (let [orig-params (:origParams data)]
|
||||
;; TODO(janherich): figure out and fix chat_id from event
|
||||
(dispatch [:command-handler! (:chat-id orig-params) orig-params
|
||||
{:result {:returned (dissoc data :origParams)}}]))
|
||||
(log/debug "Unknown jail signal " type))))
|
||||
|
||||
(register-handler-fx
|
||||
|
|
Loading…
Reference in New Issue