Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
parent
d4d4406341
commit
f16bd200e8
|
@ -1,114 +1,8 @@
|
||||||
// Send command/response
|
// Send command/response
|
||||||
|
|
||||||
function calculateFee(n, tx) {
|
|
||||||
var estimatedGas = 21000;
|
|
||||||
if (tx !== null) {
|
|
||||||
try {
|
|
||||||
estimatedGas = web3.eth.estimateGas(tx);
|
|
||||||
} catch (err) {
|
|
||||||
|
|
||||||
}
|
function amountParameterBox(params, context) {
|
||||||
}
|
|
||||||
|
|
||||||
var gasMultiplicator = Math.pow(1.4, n).toFixed(3);
|
|
||||||
var gasPrice = 211000000000;
|
|
||||||
try {
|
|
||||||
gasPrice = web3.eth.gasPrice;
|
|
||||||
} catch (err) {
|
|
||||||
|
|
||||||
}
|
|
||||||
var weiFee = gasPrice * gasMultiplicator * estimatedGas;
|
|
||||||
// force fee in eth to be of BigNumber type
|
|
||||||
var ethFee = web3.toBigNumber(web3.fromWei(weiFee, "ether"));
|
|
||||||
// always display 7 decimal places
|
|
||||||
return ethFee.toFixed(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateGasPrice(n) {
|
|
||||||
var gasMultiplicator = Math.pow(1.4, n).toFixed(3);
|
|
||||||
var gasPrice = 211000000000;
|
|
||||||
try {
|
|
||||||
gasPrice = web3.eth.gasPrice;
|
|
||||||
} catch (err) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return gasPrice * gasMultiplicator;
|
|
||||||
}
|
|
||||||
|
|
||||||
status.defineSubscription(
|
|
||||||
"calculatedFee",
|
|
||||||
{value: ["sliderValue"], tx: ["transaction"]},
|
|
||||||
function (params) {
|
|
||||||
return calculateFee(params.value, params.tx);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function getFeeExplanation(n) {
|
|
||||||
return I18n.t('send_explanation') + I18n.t('send_explanation_' + (n + 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
status.defineSubscription(
|
|
||||||
"feeExplanation",
|
|
||||||
{value: ["sliderValue"]},
|
|
||||||
function(params) {
|
|
||||||
return getFeeExplanation(params.value);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function amountParameterBox(groupChat, params, context) {
|
|
||||||
if (!params["bot-db"]) {
|
|
||||||
params["bot-db"] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
var contactAddress;
|
|
||||||
if (groupChat) {
|
|
||||||
if (params["bot-db"]["public"] && params["bot-db"]["public"]["recipient"]) {
|
|
||||||
contactAddress = params["bot-db"]["public"]["recipient"]["address"];
|
|
||||||
} else {
|
|
||||||
contactAddress = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
contactAddress = context.to;
|
|
||||||
}
|
|
||||||
|
|
||||||
var txData;
|
|
||||||
var amount;
|
|
||||||
var amountIndex = groupChat ? 1 : 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
amount = params.args[amountIndex].replace(",", ".");
|
|
||||||
txData = {
|
|
||||||
to: contactAddress,
|
|
||||||
value: web3.toWei(amount) || 0
|
|
||||||
};
|
|
||||||
} catch (err) {
|
|
||||||
amount = null;
|
|
||||||
txData = {
|
|
||||||
to: contactAddress,
|
|
||||||
value: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var sliderValue = params["bot-db"]["sliderValue"] || 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
status.setDefaultDb({
|
|
||||||
transaction: txData,
|
|
||||||
calculatedFee: calculateFee(sliderValue, txData),
|
|
||||||
feeExplanation: getFeeExplanation(sliderValue),
|
|
||||||
sliderValue: sliderValue
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
status.setDefaultDb({
|
|
||||||
transaction: txData,
|
|
||||||
calculatedFee: "0",
|
|
||||||
feeExplanation: "",
|
|
||||||
sliderValue: sliderValue
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: I18n.t('send_title'),
|
title: I18n.t('send_title'),
|
||||||
|
@ -127,128 +21,7 @@ function amountParameterBox(groupChat, params, context) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
I18n.t('send_specify_amount')
|
I18n.t('send_specify_amount')
|
||||||
),
|
)
|
||||||
status.components.touchable(
|
|
||||||
{
|
|
||||||
onPress: status.components.dispatch([status.events.FOCUS_INPUT, []])
|
|
||||||
},
|
|
||||||
status.components.view({
|
|
||||||
flexDirection: "row",
|
|
||||||
alignItems: "center",
|
|
||||||
textAlign: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}, [
|
|
||||||
status.components.text({
|
|
||||||
font: "light",
|
|
||||||
numberOfLines: 1,
|
|
||||||
ellipsizeMode: "tail",
|
|
||||||
style: {
|
|
||||||
maxWidth: 250,
|
|
||||||
fontSize: 38,
|
|
||||||
marginLeft: 8,
|
|
||||||
color: "black"
|
|
||||||
},
|
|
||||||
accessibilityLabel: "amount-text"
|
|
||||||
},
|
|
||||||
amount || "0.00"
|
|
||||||
),
|
|
||||||
status.components.text({
|
|
||||||
font: "light",
|
|
||||||
style: {
|
|
||||||
fontSize: 38,
|
|
||||||
marginLeft: 8,
|
|
||||||
color: "rgb(147, 155, 161)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
I18n.t('eth')
|
|
||||||
),
|
|
||||||
])
|
|
||||||
),
|
|
||||||
status.components.text({
|
|
||||||
style: {
|
|
||||||
fontSize: 14,
|
|
||||||
color: "rgb(147, 155, 161)",
|
|
||||||
paddingTop: 14,
|
|
||||||
paddingLeft: 16,
|
|
||||||
paddingRight: 16,
|
|
||||||
paddingBottom: 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
I18n.t('send_fee')
|
|
||||||
),
|
|
||||||
status.components.view({
|
|
||||||
flexDirection: "row"
|
|
||||||
}, [
|
|
||||||
status.components.text({
|
|
||||||
style: {
|
|
||||||
fontSize: 17,
|
|
||||||
color: "black",
|
|
||||||
paddingLeft: 16
|
|
||||||
},
|
|
||||||
accessibilityLabel: "fee-text",
|
|
||||||
}, [status.components.subscribe(["calculatedFee"])]),
|
|
||||||
status.components.text({
|
|
||||||
style: {
|
|
||||||
fontSize: 17,
|
|
||||||
color: "rgb(147, 155, 161)",
|
|
||||||
paddingLeft: 4,
|
|
||||||
paddingRight: 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
I18n.t('eth')
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
status.components.slider({
|
|
||||||
maximumValue: 2,
|
|
||||||
minimumValue: -2,
|
|
||||||
onSlidingComplete: status.components.dispatch(
|
|
||||||
[status.events.UPDATE_DB, "sliderValue"]
|
|
||||||
),
|
|
||||||
step: 1,
|
|
||||||
style: {
|
|
||||||
marginLeft: 16,
|
|
||||||
marginRight: 16
|
|
||||||
},
|
|
||||||
accessibilityLabel: "adjust-fee-slider-button"
|
|
||||||
}),
|
|
||||||
status.components.view({
|
|
||||||
flexDirection: "row"
|
|
||||||
}, [
|
|
||||||
status.components.text({
|
|
||||||
style: {
|
|
||||||
flex: 1,
|
|
||||||
fontSize: 14,
|
|
||||||
color: "rgb(147, 155, 161)",
|
|
||||||
paddingLeft: 16,
|
|
||||||
alignSelf: "flex-start"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
I18n.t('send_cheaper')
|
|
||||||
),
|
|
||||||
status.components.text({
|
|
||||||
style: {
|
|
||||||
flex: 1,
|
|
||||||
fontSize: 14,
|
|
||||||
color: "rgb(147, 155, 161)",
|
|
||||||
paddingRight: 16,
|
|
||||||
alignSelf: "flex-end",
|
|
||||||
textAlign: "right"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
I18n.t('send_faster')
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
status.components.text({
|
|
||||||
style: {
|
|
||||||
fontSize: 14,
|
|
||||||
color: "black",
|
|
||||||
paddingTop: 16,
|
|
||||||
paddingLeft: 16,
|
|
||||||
paddingRight: 16,
|
|
||||||
paddingBottom: 16,
|
|
||||||
lineHeight: 24
|
|
||||||
}
|
|
||||||
}, [status.components.subscribe(["feeExplanation"])])
|
|
||||||
])
|
])
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -264,34 +37,19 @@ var recipientSendParam = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function amountSendParam(groupChat) {
|
function amountSendParam() {
|
||||||
return {
|
return {
|
||||||
name: "amount",
|
name: "amount",
|
||||||
type: status.types.NUMBER,
|
type: status.types.NUMBER,
|
||||||
suggestions: amountParameterBox.bind(this, groupChat)
|
suggestions: amountParameterBox.bind(this)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var paramsPersonalSend = [amountSendParam(false)];
|
var paramsPersonalSend = [amountSendParam()];
|
||||||
var paramsGroupSend = [recipientSendParam, amountSendParam(true)];
|
var paramsGroupSend = [recipientSendParam, amountSendParam()];
|
||||||
|
|
||||||
function validateSend(validateRecipient, params, context) {
|
function validateSend(validateRecipient, params, context) {
|
||||||
if (!params["bot-db"]) {
|
|
||||||
params["bot-db"] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validateRecipient) {
|
|
||||||
if (!params["bot-db"]["public"]
|
|
||||||
|| !params["bot-db"]["public"]["recipient"]
|
|
||||||
|| !params["bot-db"]["public"]["recipient"]["address"]) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
"Wrong address",
|
|
||||||
"Recipient address must be specified"
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!params["amount"]) {
|
if (!params["amount"]) {
|
||||||
return {
|
return {
|
||||||
|
@ -336,73 +94,11 @@ function validateSend(validateRecipient, params, context) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
var balance = web3.eth.getBalance(context.from);
|
|
||||||
if (isNaN(balance)) {
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
I18n.t('validation_internal_title'),
|
|
||||||
I18n.t('validation_balance')
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var fee = calculateFee(
|
|
||||||
params["bot-db"]["sliderValue"],
|
|
||||||
{
|
|
||||||
to: context.to,
|
|
||||||
value: val
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (bn(val).plus(bn(web3.toWei(fee, "ether"))).greaterThan(bn(balance))) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
I18n.t('validation_title'),
|
|
||||||
I18n.t('validation_insufficient_amount')
|
|
||||||
+ web3.fromWei(balance, "ether")
|
|
||||||
+ " ETH)"
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSend(groupChat, params, context) {
|
function handleSend(params, context) {
|
||||||
var val = web3.toWei(params["amount"].replace(",", "."), "ether");
|
|
||||||
|
|
||||||
var gasPrice = calculateGasPrice(params["bot-db"]["sliderValue"]);
|
|
||||||
var data = {
|
|
||||||
from: context.from,
|
|
||||||
value: val,
|
|
||||||
gas: web3.toBigNumber(21000)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (groupChat) {
|
|
||||||
data.to = params["bot-db"]["public"]["recipient"]["address"];
|
|
||||||
} else {
|
|
||||||
data.to = context.to;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gasPrice) {
|
|
||||||
data.gasPrice = gasPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
web3.eth.sendTransaction(data, function(error, hash) {
|
|
||||||
if (error) {
|
|
||||||
// Do nothing, as error handling will be done as response to transaction.failed event from go
|
|
||||||
} else {
|
|
||||||
status.sendSignal("handler-result", {
|
|
||||||
status: "success",
|
|
||||||
hash: hash,
|
|
||||||
origParams: context["orig-params"]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// async handler, so we don't return anything immediately
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function previewSend(showRecipient, params, context) {
|
function previewSend(showRecipient, params, context) {
|
||||||
|
@ -513,8 +209,8 @@ var personalSend = {
|
||||||
description: I18n.t('send_description'),
|
description: I18n.t('send_description'),
|
||||||
params: paramsPersonalSend,
|
params: paramsPersonalSend,
|
||||||
validator: validateSend.bind(this, false),
|
validator: validateSend.bind(this, false),
|
||||||
handler: handleSend.bind(this, false),
|
handler: handleSend.bind(this),
|
||||||
asyncHandler: true,
|
asyncHandler: false,
|
||||||
preview: previewSend.bind(this, false),
|
preview: previewSend.bind(this, false),
|
||||||
shortPreview: shortPreviewSend
|
shortPreview: shortPreviewSend
|
||||||
};
|
};
|
||||||
|
@ -528,8 +224,8 @@ var groupSend = {
|
||||||
description: I18n.t('send_description'),
|
description: I18n.t('send_description'),
|
||||||
params: paramsGroupSend,
|
params: paramsGroupSend,
|
||||||
validator: validateSend.bind(this, true),
|
validator: validateSend.bind(this, true),
|
||||||
handler: handleSend.bind(this, true),
|
handler: handleSend.bind(this),
|
||||||
asyncHandler: true,
|
asyncHandler: false,
|
||||||
preview: previewSend.bind(this, true),
|
preview: previewSend.bind(this, true),
|
||||||
shortPreview: shortPreviewSend
|
shortPreview: shortPreviewSend
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,15 +4,6 @@ I18n.translations = {
|
||||||
send_description: 'Send a payment',
|
send_description: 'Send a payment',
|
||||||
send_choose_recipient: 'Choose recipient',
|
send_choose_recipient: 'Choose recipient',
|
||||||
send_specify_amount: 'Specify amount',
|
send_specify_amount: 'Specify amount',
|
||||||
send_fee: 'Fee',
|
|
||||||
send_cheaper: 'Cheaper',
|
|
||||||
send_faster: 'Faster',
|
|
||||||
send_explanation: 'This is the most amount of money that might be used to process this transaction. Your transaction will be mined ',
|
|
||||||
send_explanation_0: 'in a few minutes or more.',
|
|
||||||
send_explanation_1: 'likely within a few minutes.',
|
|
||||||
send_explanation_2: 'usually within a minute.',
|
|
||||||
send_explanation_3: 'probably within 30 seconds.',
|
|
||||||
send_explanation_4: 'probably within a few seconds.',
|
|
||||||
send_sending_to: 'to ',
|
send_sending_to: 'to ',
|
||||||
|
|
||||||
eth: 'ETH',
|
eth: 'ETH',
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
[status-im.data-store.chats :as chats-store]
|
[status-im.data-store.chats :as chats-store]
|
||||||
[status-im.data-store.messages :as messages-store]
|
[status-im.data-store.messages :as messages-store]
|
||||||
[status-im.data-store.contacts :as contacts-store]
|
[status-im.data-store.contacts :as contacts-store]
|
||||||
status-im.chat.events.commands
|
[status-im.chat.events.commands :as events.commands]
|
||||||
status-im.chat.events.requests
|
status-im.chat.events.requests
|
||||||
status-im.chat.events.send-message
|
status-im.chat.events.send-message
|
||||||
status-im.chat.events.receive-message
|
status-im.chat.events.receive-message
|
||||||
|
@ -298,6 +298,13 @@
|
||||||
(fn [cofx [chat-id opts]]
|
(fn [cofx [chat-id opts]]
|
||||||
(navigate-to-chat chat-id opts cofx)))
|
(navigate-to-chat chat-id opts cofx)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:execute-stored-command-and-return-to-chat
|
||||||
|
(fn [cofx [_ chat-id]]
|
||||||
|
(handlers-macro/merge-fx cofx
|
||||||
|
(events.commands/execute-stored-command)
|
||||||
|
(navigate-to-chat chat-id {}))))
|
||||||
|
|
||||||
(defn start-chat
|
(defn start-chat
|
||||||
"Start a chat, making sure it exists"
|
"Start a chat, making sure it exists"
|
||||||
[chat-id opts {:keys [db] :as cofx}]
|
[chat-id opts {:keys [db] :as cofx}]
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
[status-im.utils.ethereum.core :as ethereum]
|
[status-im.utils.ethereum.core :as ethereum]
|
||||||
[status-im.utils.handlers :as handlers]
|
[status-im.utils.handlers :as handlers]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.utils.platform :as platform]))
|
[status-im.utils.platform :as platform]
|
||||||
|
[status-im.chat.events.shortcuts :as shortcuts]))
|
||||||
|
|
||||||
;;;; Helper fns
|
;;;; Helper fns
|
||||||
|
|
||||||
|
@ -55,11 +56,17 @@
|
||||||
(when proceed-event-creator
|
(when proceed-event-creator
|
||||||
{:dispatch (proceed-event-creator returned)})))
|
{:dispatch (proceed-event-creator returned)})))
|
||||||
|
|
||||||
|
(defn short-preview? [opts]
|
||||||
|
(= :short-preview (:data-type opts)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:request-command-message-data
|
:request-command-message-data
|
||||||
[re-frame/trim-v (re-frame/inject-cofx :data-store/get-local-storage-data)]
|
[re-frame/trim-v (re-frame/inject-cofx :data-store/get-local-storage-data)]
|
||||||
(fn [{:keys [db]} [message opts]]
|
(fn [{:keys [db]} [message opts]]
|
||||||
(request-command-message-data db message opts)))
|
(if (and (short-preview? opts)
|
||||||
|
(shortcuts/shortcut-override? message))
|
||||||
|
(shortcuts/shortcut-override-fx db message opts)
|
||||||
|
(request-command-message-data db message opts))))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:execute-command-immediately
|
:execute-command-immediately
|
||||||
|
@ -70,3 +77,10 @@
|
||||||
{:dispatch [:request-permissions {:permissions [:read-external-storage]
|
{:dispatch [:request-permissions {:permissions [:read-external-storage]
|
||||||
:on-allowed #(re-frame/dispatch [:initialize-geth])}]}
|
:on-allowed #(re-frame/dispatch [:initialize-geth])}]}
|
||||||
(log/debug "ignoring command: " command-name))))
|
(log/debug "ignoring command: " command-name))))
|
||||||
|
|
||||||
|
;; NOTE(goranjovic) - continues execution of a command that was paused by a shortcut
|
||||||
|
(defn execute-stored-command [{:keys [db]}]
|
||||||
|
(let [{:keys [message opts]} (:commands/stored-command db)]
|
||||||
|
(-> db
|
||||||
|
(request-command-message-data message opts)
|
||||||
|
(dissoc :commands/stored-command))))
|
|
@ -10,10 +10,7 @@
|
||||||
[status-im.chat.events.commands :as commands-events]
|
[status-im.chat.events.commands :as commands-events]
|
||||||
[status-im.bots.events :as bots-events]
|
[status-im.bots.events :as bots-events]
|
||||||
[status-im.ui.components.react :as react-comp]
|
[status-im.ui.components.react :as react-comp]
|
||||||
[status-im.utils.datetime :as time]
|
[status-im.utils.handlers :as handlers]))
|
||||||
[status-im.utils.handlers :as handlers]
|
|
||||||
[status-im.utils.random :as random]
|
|
||||||
[status-im.i18n :as i18n]))
|
|
||||||
|
|
||||||
;;;; Effects
|
;;;; Effects
|
||||||
|
|
||||||
|
@ -328,15 +325,23 @@
|
||||||
proceed-events)]
|
proceed-events)]
|
||||||
{:dispatch-n events})))
|
{:dispatch-n events})))
|
||||||
|
|
||||||
|
(defn cleanup-chat-command [db]
|
||||||
|
(-> (model/set-chat-ui-props db {:sending-in-progress? false})
|
||||||
|
(clear-seq-arguments)
|
||||||
|
(set-chat-input-metadata nil)
|
||||||
|
(set-chat-input-text nil)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:cleanup-chat-command
|
||||||
|
(fn [{:keys [db]}]
|
||||||
|
{:db (cleanup-chat-command db)}))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
::send-command
|
::send-command
|
||||||
message-model/send-interceptors
|
message-model/send-interceptors
|
||||||
(fn [{:keys [db] :as cofx} [command-message]]
|
(fn [{:keys [db] :as cofx} [command-message]]
|
||||||
(let [{:keys [current-chat-id current-public-key]} db
|
(let [{:keys [current-chat-id current-public-key]} db
|
||||||
new-db (-> (model/set-chat-ui-props db {:sending-in-progress? false})
|
new-db (cleanup-chat-command db)
|
||||||
(clear-seq-arguments)
|
|
||||||
(set-chat-input-metadata nil)
|
|
||||||
(set-chat-input-text nil))
|
|
||||||
address (get-in db [:account/account :address])]
|
address (get-in db [:account/account :address])]
|
||||||
(merge {:db new-db}
|
(merge {:db new-db}
|
||||||
(message-model/process-command (assoc cofx :db new-db)
|
(message-model/process-command (assoc cofx :db new-db)
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
(ns status-im.chat.events.shortcuts
|
||||||
|
(:require [status-im.ui.screens.wallet.send.events :as send.events]
|
||||||
|
[status-im.ui.screens.wallet.choose-recipient.events :as choose-recipient.events]
|
||||||
|
[status-im.ui.screens.navigation :as navigation]
|
||||||
|
[status-im.utils.ethereum.core :as ethereum]))
|
||||||
|
|
||||||
|
;; TODO(goranjovic) - update to include tokens in https://github.com/status-im/status-react/issues/3233
|
||||||
|
(defn- transaction-details [contact]
|
||||||
|
(-> contact
|
||||||
|
(select-keys [:name :address :whisper-identity])
|
||||||
|
(assoc :symbol :ETH
|
||||||
|
:gas (ethereum/estimate-gas :ETH)
|
||||||
|
:from-chat? true)))
|
||||||
|
|
||||||
|
(defn send-shortcut-fx [db contact params]
|
||||||
|
(merge {:db (-> db
|
||||||
|
(send.events/set-and-validate-amount-db (:amount params))
|
||||||
|
(choose-recipient.events/fill-request-details (transaction-details contact))
|
||||||
|
(navigation/navigate-to :wallet-send-transaction-chat))}
|
||||||
|
(send.events/update-gas-price db false)))
|
||||||
|
|
||||||
|
(def shortcuts
|
||||||
|
{"send" send-shortcut-fx})
|
||||||
|
|
||||||
|
(defn shortcut-override? [message]
|
||||||
|
(get shortcuts (get-in message [:content :command])))
|
||||||
|
|
||||||
|
(defn shortcut-override-fx [db {:keys [chat-id content] :as message} opts]
|
||||||
|
(let [command (:command content)
|
||||||
|
contact (get-in db [:contacts/contacts chat-id])
|
||||||
|
shortcut-specific-fx (get shortcuts command)
|
||||||
|
stored-command {:message message :opts opts}]
|
||||||
|
(-> db
|
||||||
|
(assoc :commands/stored-command stored-command)
|
||||||
|
;; NOTE(goranjovic) - stores the command if we want to continue it after
|
||||||
|
;; shortcut has been executed, see `:execute-stored-command`
|
||||||
|
(shortcut-specific-fx contact (:params content))
|
||||||
|
;; TODO(goranjovic) - replace this dispatch with a function call
|
||||||
|
;; Need to refactor chat events namespaces for this to avoid circular dependecy
|
||||||
|
(assoc :dispatch [:cleanup-chat-command]))))
|
|
@ -147,6 +147,7 @@
|
||||||
:contacts/click-handler
|
:contacts/click-handler
|
||||||
:contacts/click-action
|
:contacts/click-action
|
||||||
:contacts/click-params
|
:contacts/click-params
|
||||||
|
:commands/stored-command
|
||||||
:group/selected-contacts
|
:group/selected-contacts
|
||||||
:accounts/accounts
|
:accounts/accounts
|
||||||
:accounts/create
|
:accounts/create
|
||||||
|
|
|
@ -122,6 +122,7 @@
|
||||||
:dapp-description dapp-description
|
:dapp-description dapp-description
|
||||||
:wallet-onboarding-setup wallet.onboarding.setup/screen
|
:wallet-onboarding-setup wallet.onboarding.setup/screen
|
||||||
:wallet-send-transaction send-transaction
|
:wallet-send-transaction send-transaction
|
||||||
|
:wallet-send-transaction-chat send-transaction
|
||||||
:wallet-transaction-sent transaction-sent
|
:wallet-transaction-sent transaction-sent
|
||||||
:wallet-request-transaction request-transaction
|
:wallet-request-transaction request-transaction
|
||||||
:wallet-send-transaction-request send-transaction-request
|
:wallet-send-transaction-request send-transaction-request
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
toggled-state (if (= :on flashlight-state) :off :on)]
|
toggled-state (if (= :on flashlight-state) :off :on)]
|
||||||
(assoc-in db [:wallet :send-transaction :camera-flashlight] toggled-state))))
|
(assoc-in db [:wallet :send-transaction :camera-flashlight] toggled-state))))
|
||||||
|
|
||||||
(defn- fill-request-details [db {:keys [address name value symbol gas gasPrice whisper-identity]}]
|
(defn- fill-request-details [db {:keys [address name value symbol gas gasPrice whisper-identity from-chat?]}]
|
||||||
{:pre [(not (nil? address))]}
|
{:pre [(not (nil? address))]}
|
||||||
(update-in
|
(update-in
|
||||||
db [:wallet :send-transaction]
|
db [:wallet :send-transaction]
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
symbol (assoc :symbol symbol)
|
symbol (assoc :symbol symbol)
|
||||||
gas (assoc :gas (money/bignumber gas))
|
gas (assoc :gas (money/bignumber gas))
|
||||||
gasPrice (assoc :gas-price (money/bignumber gasPrice))
|
gasPrice (assoc :gas-price (money/bignumber gasPrice))
|
||||||
|
from-chat? (assoc :from-chat? from-chat?)
|
||||||
(and symbol (not gasPrice))
|
(and symbol (not gasPrice))
|
||||||
(assoc :gas-price (ethereum/estimate-gas symbol)))))
|
(assoc :gas-price (ethereum/estimate-gas symbol)))))
|
||||||
|
|
||||||
|
|
|
@ -237,13 +237,6 @@
|
||||||
:from-chat? from-chat?})
|
:from-chat? from-chat?})
|
||||||
:dispatch [:navigate-to-modal :wallet-send-transaction-modal]}))
|
:dispatch [:navigate-to-modal :wallet-send-transaction-modal]}))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
|
||||||
:wallet/update-gas-price
|
|
||||||
(fn [{:keys [db]} [_ edit?]]
|
|
||||||
{:update-gas-price {:web3 (:web3 db)
|
|
||||||
:success-event :wallet/update-gas-price-success
|
|
||||||
:edit? edit?}}))
|
|
||||||
|
|
||||||
(handlers/register-handler-db
|
(handlers/register-handler-db
|
||||||
:wallet/update-gas-price-success
|
:wallet/update-gas-price-success
|
||||||
(fn [db [_ price edit?]]
|
(fn [db [_ price edit?]]
|
||||||
|
|
|
@ -68,14 +68,17 @@
|
||||||
(re-frame/dispatch [::transaction-completed {:id (name (key result)) :response (second result)} modal?]))
|
(re-frame/dispatch [::transaction-completed {:id (name (key result)) :response (second result)} modal?]))
|
||||||
;;;; Handlers
|
;;;; Handlers
|
||||||
|
|
||||||
|
(defn set-and-validate-amount-db [db amount]
|
||||||
|
(let [{:keys [value error]} (wallet.db/parse-amount amount)]
|
||||||
|
(-> db
|
||||||
|
(assoc-in [:wallet :send-transaction :amount] (money/ether->wei value))
|
||||||
|
(assoc-in [:wallet :send-transaction :amount-text] amount)
|
||||||
|
(assoc-in [:wallet :send-transaction :amount-error] error))))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:wallet.send/set-and-validate-amount
|
:wallet.send/set-and-validate-amount
|
||||||
(fn [{:keys [db]} [_ amount]]
|
(fn [{:keys [db]} [_ amount]]
|
||||||
(let [{:keys [value error]} (wallet.db/parse-amount amount)]
|
{:db (set-and-validate-amount-db db amount)}))
|
||||||
{:db (-> db
|
|
||||||
(assoc-in [:wallet :send-transaction :amount] (money/ether->wei value))
|
|
||||||
(assoc-in [:wallet :send-transaction :amount-text] amount)
|
|
||||||
(assoc-in [:wallet :send-transaction :amount-error] error))})))
|
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:wallet.send/set-symbol
|
:wallet.send/set-symbol
|
||||||
|
@ -347,10 +350,21 @@
|
||||||
assoc
|
assoc
|
||||||
:gas (ethereum/estimate-gas (get-in db [:wallet :send-transaction :symbol])))}))
|
:gas (ethereum/estimate-gas (get-in db [:wallet :send-transaction :symbol])))}))
|
||||||
|
|
||||||
|
(defn update-gas-price [db edit?]
|
||||||
|
{:update-gas-price {:web3 (:web3 db)
|
||||||
|
:success-event :wallet/update-gas-price-success
|
||||||
|
:edit? edit?}})
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:wallet/update-gas-price
|
||||||
|
(fn [{:keys [db]} [_ edit?]]
|
||||||
|
(update-gas-price db edit?)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:close-transaction-sent-screen
|
:close-transaction-sent-screen
|
||||||
(fn [{:keys [db]} _]
|
(fn [{:keys [db]} [_ chat-id]]
|
||||||
{:dispatch (if (= :wallet-send-transaction (second (:navigation-stack db)))
|
{:dispatch (condp = (second (:navigation-stack db))
|
||||||
[:navigate-to-clean :wallet]
|
:wallet-send-transaction [:navigate-to-clean :wallet]
|
||||||
[:navigate-back])
|
:wallet-send-transaction-chat [:execute-stored-command-and-return-to-chat chat-id]
|
||||||
|
[:navigate-back])
|
||||||
:dispatch-later [{:ms 400 :dispatch [:check-transactions-queue]}]}))
|
:dispatch-later [{:ms 400 :dispatch [:check-transactions-queue]}]}))
|
||||||
|
|
|
@ -12,26 +12,27 @@
|
||||||
[status-im.utils.platform :as platform]))
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
(defview transaction-sent [& [modal?]]
|
(defview transaction-sent [& [modal?]]
|
||||||
[react/view wallet.styles/wallet-modal-container
|
(letsubs [chat-id [:get-current-chat-id]]
|
||||||
[status-bar/status-bar {:type (if modal? :modal-wallet :transparent)}]
|
[react/view wallet.styles/wallet-modal-container
|
||||||
[react/view styles/transaction-sent-container
|
[status-bar/status-bar {:type (if modal? :modal-wallet :transparent)}]
|
||||||
[react/view styles/ok-icon-container
|
[react/view styles/transaction-sent-container
|
||||||
[vi/icon :icons/ok {:color components.styles/color-blue4}]]
|
[react/view styles/ok-icon-container
|
||||||
[react/text {:style styles/transaction-sent
|
[vi/icon :icons/ok {:color components.styles/color-blue4}]]
|
||||||
:font (if platform/android? :medium :default)
|
[react/text {:style styles/transaction-sent
|
||||||
:accessibility-label :transaction-sent-text}
|
:font (if platform/android? :medium :default)
|
||||||
(i18n/label :t/transaction-sent)]
|
:accessibility-label :transaction-sent-text}
|
||||||
[react/view styles/gap]
|
(i18n/label :t/transaction-sent)]
|
||||||
[react/text {:style styles/transaction-sent-description} (i18n/label :t/transaction-description)]]
|
[react/view styles/gap]
|
||||||
[react/view components.styles/flex]
|
[react/text {:style styles/transaction-sent-description} (i18n/label :t/transaction-description)]]
|
||||||
[components/separator]
|
[react/view components.styles/flex]
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:close-transaction-sent-screen])
|
[components/separator]
|
||||||
:accessibility-label :got-it-button}
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:close-transaction-sent-screen chat-id])
|
||||||
[react/view styles/got-it-container
|
:accessibility-label :got-it-button}
|
||||||
[react/text {:style styles/got-it
|
[react/view styles/got-it-container
|
||||||
:font (if platform/android? :medium :default)
|
[react/text {:style styles/got-it
|
||||||
:uppercase? true}
|
:font (if platform/android? :medium :default)
|
||||||
(i18n/label :t/got-it)]]]])
|
:uppercase? true}
|
||||||
|
(i18n/label :t/got-it)]]]]))
|
||||||
|
|
||||||
(defview transaction-sent-modal []
|
(defview transaction-sent-modal []
|
||||||
[transaction-sent true])
|
[transaction-sent true])
|
||||||
|
|
|
@ -212,13 +212,13 @@
|
||||||
:on-content-size-change #(when (and (not modal?) scroll @scroll)
|
:on-content-size-change #(when (and (not modal?) scroll @scroll)
|
||||||
(.scrollToEnd @scroll))}
|
(.scrollToEnd @scroll))}
|
||||||
[react/view styles/send-transaction-form
|
[react/view styles/send-transaction-form
|
||||||
[components/recipient-selector {:disabled? modal?
|
[components/recipient-selector {:disabled? (or from-chat? modal?)
|
||||||
:address to
|
:address to
|
||||||
:name to-name}]
|
:name to-name}]
|
||||||
[components/asset-selector {:disabled? modal?
|
[components/asset-selector {:disabled? (or from-chat? modal?)
|
||||||
:type :send
|
:type :send
|
||||||
:symbol symbol}]
|
:symbol symbol}]
|
||||||
[components/amount-selector {:disabled? modal?
|
[components/amount-selector {:disabled? (or from-chat? modal?)
|
||||||
:error (or amount-error
|
:error (or amount-error
|
||||||
(when-not sufficient-funds? (i18n/label :t/wallet-insufficient-funds)))
|
(when-not sufficient-funds? (i18n/label :t/wallet-insufficient-funds)))
|
||||||
:input-options {:max-length 21
|
:input-options {:max-length 21
|
||||||
|
|
Loading…
Reference in New Issue