This commit is contained in:
parent
caba84e439
commit
32bbf4e533
|
@ -1,30 +1,17 @@
|
|||
|
||||
// Send command/response
|
||||
|
||||
|
||||
function amountParameterBox(params, context) {
|
||||
|
||||
|
||||
var assetSendParam = {
|
||||
name: "asset",
|
||||
type: status.types.TEXT,
|
||||
suggestions: function (params) {
|
||||
return {
|
||||
title: I18n.t('send_title'),
|
||||
showBack: true,
|
||||
markup: status.components.view({
|
||||
flex: 1
|
||||
}, [
|
||||
status.components.text({
|
||||
style: {
|
||||
fontSize: 14,
|
||||
color: "rgb(147, 155, 161)",
|
||||
paddingTop: 12,
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
paddingBottom: 20
|
||||
}
|
||||
},
|
||||
I18n.t('send_specify_amount')
|
||||
)
|
||||
])
|
||||
markup: status.components.chooseAsset("asset", 0)
|
||||
};
|
||||
}
|
||||
},
|
||||
placeholder: I18n.t('currency_placeholder')
|
||||
};
|
||||
|
||||
|
||||
var recipientSendParam = {
|
||||
name: "recipient",
|
||||
|
@ -41,15 +28,26 @@ function amountSendParam() {
|
|||
return {
|
||||
name: "amount",
|
||||
type: status.types.NUMBER,
|
||||
suggestions: amountParameterBox.bind(this)
|
||||
placeholder: I18n.t('amount_placeholder')
|
||||
};
|
||||
}
|
||||
|
||||
var paramsPersonalSend = [amountSendParam()];
|
||||
var paramsPersonalSend = [assetSendParam, amountSendParam()];
|
||||
var paramsGroupSend = [recipientSendParam, amountSendParam()];
|
||||
|
||||
function validateSend(validateRecipient, params, context) {
|
||||
|
||||
var allowedAssets = context["allowed-assets"];
|
||||
var asset = params["asset"];
|
||||
|
||||
if(!allowedAssets.hasOwnProperty(asset)){
|
||||
return {
|
||||
markup: status.components.validationMessage(
|
||||
"Invalid asset",
|
||||
"Unknown token - " + asset
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
if (!params["amount"]) {
|
||||
return {
|
||||
|
@ -62,11 +60,12 @@ function validateSend(validateRecipient, params, context) {
|
|||
|
||||
var amount = params["amount"].replace(",", ".");
|
||||
var amountSplitted = amount.split(".");
|
||||
if (amountSplitted.length === 2 && amountSplitted[1].length > 18) {
|
||||
var decimals = allowedAssets[asset];
|
||||
if (amountSplitted.length === 2 && amountSplitted[1].length > decimals) {
|
||||
return {
|
||||
markup: status.components.validationMessage(
|
||||
I18n.t('validation_title'),
|
||||
I18n.t('validation_amount_is_too_small')
|
||||
I18n.t('validation_amount_is_too_small') + decimals
|
||||
)
|
||||
};
|
||||
}
|
||||
|
@ -135,6 +134,17 @@ status.response(groupSend);
|
|||
|
||||
// Request command
|
||||
|
||||
var assetRequestParam = {
|
||||
name: "asset",
|
||||
type: status.types.TEXT,
|
||||
suggestions: function (params) {
|
||||
return {
|
||||
markup: status.components.chooseAsset("asset", 0)
|
||||
};
|
||||
},
|
||||
placeholder: I18n.t('currency_placeholder')
|
||||
};
|
||||
|
||||
var recipientRequestParam = {
|
||||
name: "recipient",
|
||||
type: status.types.TEXT,
|
||||
|
@ -148,15 +158,17 @@ var recipientRequestParam = {
|
|||
|
||||
var amountRequestParam = {
|
||||
name: "amount",
|
||||
type: status.types.NUMBER
|
||||
type: status.types.NUMBER,
|
||||
placeholder: I18n.t('amount_placeholder')
|
||||
};
|
||||
|
||||
var paramsPersonalRequest = [amountRequestParam];
|
||||
var paramsPersonalRequest = [assetRequestParam, amountRequestParam];
|
||||
var paramsGroupRequest = [recipientRequestParam, amountRequestParam];
|
||||
|
||||
function handlePersonalRequest(params, context) {
|
||||
var val = params["amount"].replace(",", ".");
|
||||
var network = context["network"];
|
||||
var asset = params["asset"];
|
||||
|
||||
return {
|
||||
event: "request",
|
||||
|
@ -165,8 +177,9 @@ function handlePersonalRequest(params, context) {
|
|||
params: {
|
||||
network: network,
|
||||
amount: val,
|
||||
asset: asset
|
||||
},
|
||||
prefill: [val]
|
||||
prefill: [asset, val]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -194,7 +207,7 @@ function handleGroupRequest(params, context) {
|
|||
};
|
||||
}
|
||||
|
||||
function validateRequest(validateRecipient, params) {
|
||||
function validateRequest(validateRecipient, params, context) {
|
||||
if (!params["bot-db"]) {
|
||||
params["bot-db"] = {};
|
||||
}
|
||||
|
@ -210,6 +223,18 @@ function validateRequest(validateRecipient, params) {
|
|||
}
|
||||
}
|
||||
|
||||
var allowedAssets = context["allowed-assets"];
|
||||
var asset = params["asset"];
|
||||
|
||||
if(!allowedAssets.hasOwnProperty(asset)){
|
||||
return {
|
||||
markup: status.components.validationMessage(
|
||||
"Invalid asset",
|
||||
"Unknown token - " + asset
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
if (!params["amount"]) {
|
||||
return {
|
||||
markup: status.components.validationMessage(
|
||||
|
@ -221,11 +246,12 @@ function validateRequest(validateRecipient, params) {
|
|||
|
||||
var amount = params.amount.replace(",", ".");
|
||||
var amountSplitted = amount.split(".");
|
||||
if (amountSplitted.length === 2 && amountSplitted[1].length > 18) {
|
||||
var decimals = allowedAssets[asset];
|
||||
if (amountSplitted.length === 2 && amountSplitted[1].length > decimals) {
|
||||
return {
|
||||
markup: status.components.validationMessage(
|
||||
I18n.t('validation_title'),
|
||||
I18n.t('validation_amount_is_too_small')
|
||||
I18n.t('validation_amount_is_too_small') + decimals
|
||||
)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ I18n.translations = {
|
|||
send_specify_amount: 'Specify amount',
|
||||
send_sending_to: 'to ',
|
||||
|
||||
currency_placeholder: 'Currency',
|
||||
amount_placeholder: 'Amount',
|
||||
|
||||
eth: 'ETH',
|
||||
|
||||
request_title: 'Request ETH',
|
||||
|
@ -20,7 +23,7 @@ I18n.translations = {
|
|||
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. Max number of decimals is 18.',
|
||||
validation_amount_is_too_small: 'Max number of decimals is ',
|
||||
validation_insufficient_amount: 'Insufficient funds for gas * price + value (balance '
|
||||
}
|
||||
|
||||
|
|
|
@ -215,6 +215,14 @@ function chooseContact(titleText, botDbKey, argumentIndex) {
|
|||
}];
|
||||
}
|
||||
|
||||
function chooseAsset(botDbKey, argumentIndex) {
|
||||
return ['choose-asset', {
|
||||
"bot-db-key": botDbKey,
|
||||
index: argumentIndex
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
function separator() {
|
||||
return ['separator'];
|
||||
}
|
||||
|
@ -276,6 +284,7 @@ var status = {
|
|||
webView: webView,
|
||||
validationMessage: validationMessage,
|
||||
bridgedWebView: bridgedWebView,
|
||||
chooseAsset: chooseAsset,
|
||||
chooseContact: chooseContact,
|
||||
subscribe: subscribe,
|
||||
dispatch: dispatch,
|
||||
|
|
|
@ -6,24 +6,39 @@
|
|||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.chat.events.shortcuts :as shortcuts]))
|
||||
[status-im.chat.events.shortcuts :as shortcuts]
|
||||
[status-im.utils.ethereum.tokens :as tokens]))
|
||||
|
||||
;;;; Helper fns
|
||||
|
||||
;;TODO(goranjovic): currently we only allow tokens which are enabled in Manage assets here
|
||||
;; because balances are only fetched for them. Revisit this decision with regard to battery/network consequences
|
||||
;; if we were to update all balances.
|
||||
(defn- allowed-assets [network account]
|
||||
(let [chain (keyword (ethereum/network-names network))
|
||||
visible-token-symbols (get-in account [:settings :wallet :visible-tokens chain])]
|
||||
(->> (tokens/tokens-for chain)
|
||||
(filter #(not (:nft? %)))
|
||||
(filter #(contains? visible-token-symbols (:symbol %)))
|
||||
(map #(vector (-> % :symbol clojure.core/name)
|
||||
(:decimals %)))
|
||||
(into {"ETH" 18}))))
|
||||
|
||||
(defn- generate-context
|
||||
"Generates context for jail call"
|
||||
[current-account-id chat-id group-chat? to network]
|
||||
[account current-account-id chat-id group-chat? to network]
|
||||
(merge {:platform platform/os
|
||||
:network (ethereum/network-names network)
|
||||
:from current-account-id
|
||||
:to to
|
||||
:allowed-assets (clj->js (allowed-assets network account))
|
||||
:chat {:chat-id chat-id
|
||||
:group-chat (boolean group-chat?)}}
|
||||
i18n/delimeters))
|
||||
|
||||
(defn request-command-message-data
|
||||
"Requests command message data from jail"
|
||||
[{:contacts/keys [contacts] :keys [network] :as db}
|
||||
[{:contacts/keys [contacts] :account/keys [account] :keys [network] :as db}
|
||||
{{:keys [command command-scope-bitmask bot params type]} :content
|
||||
:keys [chat-id group-id] :as message}
|
||||
{:keys [data-type] :as opts}]
|
||||
|
@ -36,7 +51,7 @@
|
|||
to (get-in contacts [chat-id :address])
|
||||
address (get-in db [:account/account :address])
|
||||
jail-params {:parameters params
|
||||
:context (generate-context address chat-id (models.message/group-message? message) to network)}]
|
||||
:context (generate-context account address chat-id (models.message/group-message? message) to network)}]
|
||||
{:db db
|
||||
:call-jail [{:jail-id bot
|
||||
:path path
|
||||
|
|
|
@ -208,6 +208,7 @@
|
|||
(not prevent-auto-focus?)
|
||||
(merge fx' (chat-input-focus (:db fx') :seq-input-ref)))))))
|
||||
|
||||
;; TODO(goranjovic) - generalize setting something as a command argument
|
||||
(defn set-contact-as-command-argument
|
||||
"Sets contact as command argument for active chat"
|
||||
[db {:keys [bot-db-key contact arg-index]}]
|
||||
|
@ -233,6 +234,31 @@
|
|||
(min (count input-text)))]
|
||||
(merge fx (update-text-selection new-db new-selection)))))))
|
||||
|
||||
;; TODO(goranjovic) - generalize setting something as a command argument
|
||||
(defn set-asset-as-command-argument
|
||||
"Sets asset as command argument for active chat"
|
||||
[db {:keys [bot-db-key asset arg-index]}]
|
||||
(let [name (string/replace (name (:symbol asset)) (re-pattern constants/arg-wrapping-char) "")
|
||||
command-owner (get-in (input-model/selected-chat-command db) [:command :owner-id])]
|
||||
(-> db
|
||||
(set-command-argument arg-index name true)
|
||||
(bots-events/set-in-bot-db {:bot command-owner
|
||||
:path [:public (keyword bot-db-key)]
|
||||
:value asset})
|
||||
(as-> fx
|
||||
(let [{:keys [current-chat-id]
|
||||
:as new-db} (:db fx)
|
||||
arg-position (input-model/argument-position new-db)
|
||||
input-text (get-in new-db [:chats current-chat-id :input-text])
|
||||
command-args (cond-> (input-model/split-command-args input-text)
|
||||
(input-model/text-ends-with-space? input-text) (conj ""))
|
||||
new-selection (->> command-args
|
||||
(take (+ 3 arg-position))
|
||||
(input-model/join-command-args)
|
||||
count
|
||||
(min (count input-text)))]
|
||||
(merge fx (update-text-selection new-db new-selection)))))))
|
||||
|
||||
;; 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}]
|
||||
|
@ -468,6 +494,12 @@
|
|||
(fn [{:keys [db]} [params]]
|
||||
(set-contact-as-command-argument db params)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:set-asset-as-command-argument
|
||||
[re-frame/trim-v]
|
||||
(fn [{:keys [db]} [params]]
|
||||
(set-asset-as-command-argument db params)))
|
||||
|
||||
(handlers/register-handler-db
|
||||
:show-suggestions
|
||||
(fn [db _]
|
||||
|
|
|
@ -2,26 +2,31 @@
|
|||
(: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]))
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.ethereum.tokens :as tokens]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
;; TODO(goranjovic) - update to include tokens in https://github.com/status-im/status-react/issues/3233
|
||||
(defn- transaction-details [contact]
|
||||
(defn- transaction-details [contact symbol]
|
||||
(-> contact
|
||||
(select-keys [:name :address :whisper-identity])
|
||||
(assoc :symbol :ETH
|
||||
:gas (ethereum/estimate-gas :ETH)
|
||||
(assoc :symbol symbol
|
||||
:gas (ethereum/estimate-gas symbol)
|
||||
:from-chat? true)))
|
||||
|
||||
(defn send-shortcut-fx [{:account/keys [account] :as db} contact params]
|
||||
(let [chain (keyword (ethereum/network-names (:network db)))
|
||||
symbol (-> params :asset keyword)
|
||||
{:keys [decimals]} (tokens/asset-for chain symbol)]
|
||||
(merge {:db (-> db
|
||||
(send.events/set-and-validate-amount-db (:amount params) :ETH 18)
|
||||
(choose-recipient.events/fill-request-details (transaction-details contact))
|
||||
(send.events/set-and-validate-amount-db (:amount params) symbol decimals)
|
||||
(choose-recipient.events/fill-request-details (transaction-details contact symbol))
|
||||
(update-in [:wallet :send-transaction] dissoc :id :password :wrong-password?)
|
||||
(navigation/navigate-to
|
||||
(if (:wallet-set-up-passed? account)
|
||||
:wallet-send-transaction-chat
|
||||
:wallet-onboarding-setup)))}
|
||||
(send.events/update-gas-price db false)))
|
||||
(send.events/update-gas-price db false))))
|
||||
|
||||
(def shortcuts
|
||||
{"send" send-shortcut-fx})
|
||||
|
|
|
@ -378,7 +378,7 @@
|
|||
{:params (cond-> params
|
||||
(= (:name command) constants/command-send)
|
||||
(assoc :network (ethereum/network-names network)
|
||||
:fiat-amount (money/usd-amount (:amount params) prices)
|
||||
:fiat-amount (money/usd-amount (:amount params) (-> params :asset keyword) prices)
|
||||
:tx-hash tx-hash))})
|
||||
content' (assoc content
|
||||
:command (:name command)
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
:text-align-vertical :center
|
||||
:flex 1
|
||||
:android {:top -1}
|
||||
:ios {:line-height min-input-height}})
|
||||
:ios {:line-height 43}})
|
||||
|
||||
(defnstyle seq-input-text [left container-width]
|
||||
{:min-width (- container-width left)
|
||||
|
|
|
@ -288,15 +288,13 @@
|
|||
(fn [[{:keys [input-text]} command]]
|
||||
(when (and (string/ends-with? (or input-text "") chat-constants/spacing-char)
|
||||
(not (get-in command [:command :sequential-params])))
|
||||
(let [input (string/trim (or input-text ""))
|
||||
real-args (remove string/blank? (:args command))]
|
||||
(let [real-args (remove string/blank? (:args command))]
|
||||
(cond
|
||||
(and command (empty? real-args))
|
||||
(get-in command [:command :params 0 :placeholder])
|
||||
|
||||
(and command
|
||||
(= (count real-args) 1)
|
||||
(input-model/text-ends-with-space? input))
|
||||
(= (count real-args) 1))
|
||||
(get-in command [:command :params 1 :placeholder]))))))
|
||||
|
||||
(reg-sub
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
(ns status-im.chat.views.api.choose-asset
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.money :as money]
|
||||
[status-im.chat.views.api.styles :as styles]))
|
||||
|
||||
(defn clean-asset [asset]
|
||||
(select-keys asset [:name :symbol :decimals :address]))
|
||||
|
||||
(defn- render-asset [arg-index bot-db-key]
|
||||
(fn [{:keys [name symbol amount decimals] :as asset}]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch
|
||||
[:set-asset-as-command-argument {:arg-index arg-index
|
||||
:bot-db-key bot-db-key
|
||||
:asset (clean-asset asset)}])}
|
||||
[react/view styles/asset-container
|
||||
[react/view styles/asset-main
|
||||
[react/image {:source (-> asset :icon :source)
|
||||
:style styles/asset-icon}]
|
||||
[react/text {:style styles/asset-symbol} symbol]
|
||||
[react/text {:style styles/asset-name} name]]
|
||||
[react/text {:style styles/asset-balance}
|
||||
(str (money/internal->formatted amount symbol decimals))]]]))
|
||||
|
||||
(def assets-separator [react/view styles/asset-separator])
|
||||
|
||||
(defview choose-asset-view [{arg-index :index
|
||||
bot-db-key :bot-db-key}]
|
||||
(letsubs [assets [:wallet/visible-assets-with-amount]]
|
||||
[react/view
|
||||
[list/flat-list {:data (filter #(not (:nft? %)) assets)
|
||||
:key-fn (comp name :symbol)
|
||||
:render-fn (render-asset arg-index bot-db-key)
|
||||
:enableEmptySections true
|
||||
:separator assets-separator
|
||||
:keyboardShouldPersistTaps :always
|
||||
:bounces false}]]))
|
|
@ -0,0 +1,35 @@
|
|||
(ns status-im.chat.views.api.styles
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def asset-container
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between
|
||||
:padding-vertical 11})
|
||||
|
||||
(def asset-main
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def asset-icon
|
||||
{:width 30
|
||||
:height 30
|
||||
:margin-left 14
|
||||
:margin-right 12})
|
||||
|
||||
(def asset-symbol
|
||||
{:color colors/black})
|
||||
|
||||
(def asset-name
|
||||
{:color colors/gray
|
||||
:padding-left 4})
|
||||
|
||||
(def asset-balance
|
||||
{:color colors/gray
|
||||
:padding-right 14})
|
||||
|
||||
(def asset-separator
|
||||
{:height 1
|
||||
:background-color colors/gray-light
|
||||
:margin-left 56})
|
|
@ -77,7 +77,7 @@
|
|||
(defview message-content-command-send
|
||||
[{:keys [content timestamp-str outgoing group-chat]}]
|
||||
(letsubs [network [:network-name]]
|
||||
(let [{{:keys [amount fiat-amount tx-hash] send-network :network} :params} content
|
||||
(let [{{:keys [amount fiat-amount tx-hash asset] send-network :network} :params} content
|
||||
recipient-name (get-in content [:params :bot-db :public :recipient])
|
||||
network-mismatch? (and (seq send-network) (not= network send-network))]
|
||||
[react/view style/command-send-message-view
|
||||
|
@ -91,7 +91,7 @@
|
|||
"."]
|
||||
[react/text {:style (style/command-send-currency-text outgoing)
|
||||
:font :default}
|
||||
(i18n/label :eth)]]]]
|
||||
asset]]]]
|
||||
(when fiat-amount
|
||||
[react/view style/command-send-fiat-amount
|
||||
[react/text {:style style/command-send-fiat-amount-text}
|
||||
|
|
|
@ -89,9 +89,9 @@
|
|||
(merge command {:prefill prefill
|
||||
:prefill-bot-db (or prefill-bot-db prefillBotDb)})
|
||||
command)
|
||||
{:keys [amount] request-network :network} params
|
||||
{:keys [amount asset] request-network :network} params
|
||||
recipient-name (get-in params [:bot-db :public :recipient])
|
||||
usd-amount (money/usd-amount amount prices)
|
||||
usd-amount (money/usd-amount amount (keyword asset) prices)
|
||||
network-mismatch? (and request-network (not= request-network network))
|
||||
on-press-handler (cond
|
||||
network-mismatch? nil
|
||||
|
@ -117,7 +117,7 @@
|
|||
"."]
|
||||
[text {:style (st/command-request-currency-text outgoing)
|
||||
:font :default}
|
||||
(i18n/label :eth)]]]
|
||||
asset]]]
|
||||
[view st/command-request-fiat-amount-row
|
||||
[text {:style st/command-request-fiat-amount-text}
|
||||
(str "~ " usd-amount " " (i18n/label :usd-currency))]]
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
[status-im.ui.components.react :as components]
|
||||
[status-im.chat.views.input.validation-messages :as chat-validation-messages]
|
||||
[status-im.chat.views.api.choose-contact :as choose-contact]
|
||||
[status-im.chat.views.api.choose-asset :as choose-asset]
|
||||
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
||||
[status-im.ui.components.chat-preview :as chat-preview]
|
||||
[status-im.utils.handlers :refer [register-handler]]
|
||||
|
@ -32,6 +33,7 @@
|
|||
:activity-indicator components/activity-indicator
|
||||
:validation-message chat-validation-messages/validation-message
|
||||
:choose-contact choose-contact/choose-contact-view
|
||||
:choose-asset choose-asset/choose-asset-view
|
||||
:separator parameter-box-separator})
|
||||
|
||||
(defn get-element [n]
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
[status-im.ui.components.common.common :as components.common]))
|
||||
|
||||
(defn command-short-preview
|
||||
[{:keys [command] {:keys [amount]} :params}]
|
||||
[{:keys [command] {:keys [amount asset]} :params}]
|
||||
[chat-preview/text {}
|
||||
(str
|
||||
(i18n/label (if (= command constants/command-request)
|
||||
|
@ -27,7 +27,7 @@
|
|||
:command-sending))
|
||||
(i18n/label-number amount)
|
||||
" "
|
||||
(i18n/label :eth))])
|
||||
asset)])
|
||||
|
||||
(defn message-content-text [{:keys [content] :as message}]
|
||||
[react/view styles/last-message-container
|
||||
|
|
|
@ -19,12 +19,15 @@
|
|||
{:gas (ethereum/estimate-gas symbol)
|
||||
:symbol symbol}))
|
||||
|
||||
(def transaction-request-default
|
||||
{:symbol :ETH})
|
||||
|
||||
(defmethod navigation/preload-data! :wallet-request-transaction
|
||||
[db [event]]
|
||||
(if (= event :navigate-back)
|
||||
db
|
||||
(-> db
|
||||
(update :wallet dissoc :request-transaction)
|
||||
(assoc-in [:wallet :request-transaction] transaction-request-default)
|
||||
(assoc-in [:wallet :send-transaction] transaction-send-default))))
|
||||
|
||||
(defmethod navigation/preload-data! :wallet-send-transaction
|
||||
|
|
|
@ -10,21 +10,21 @@
|
|||
(handlers/register-handler-fx
|
||||
::wallet-send-chat-request
|
||||
[re-frame/trim-v]
|
||||
(fn [{{:contacts/keys [contacts]} :db :as cofx} [amount]]
|
||||
(fn [{{:contacts/keys [contacts]} :db :as cofx} [asset amount]]
|
||||
(handlers-macro/merge-fx cofx
|
||||
{:dispatch [:send-current-message]}
|
||||
(input-events/select-chat-input-command
|
||||
(assoc (get-in contacts chat-const/request-command-ref) :prefill [amount]) nil true))))
|
||||
(assoc (get-in contacts chat-const/request-command-ref) :prefill [asset amount]) nil true))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet-send-request
|
||||
[re-frame/trim-v]
|
||||
(fn [_ [whisper-identity amount]]
|
||||
(fn [_ [whisper-identity amount symbol decimals]]
|
||||
(assert whisper-identity)
|
||||
{:dispatch-n [[:navigate-back]
|
||||
[:navigate-to-clean :home]
|
||||
[:add-chat-loaded-event whisper-identity
|
||||
[::wallet-send-chat-request (str (money/wei->ether amount))]]
|
||||
[::wallet-send-chat-request (name symbol) (str (money/internal->formatted amount symbol decimals))]]
|
||||
[:start-chat whisper-identity]]}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
|
@ -34,9 +34,15 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:wallet.request/set-and-validate-amount
|
||||
(fn [{:keys [db]} [_ amount]]
|
||||
(let [{:keys [value error]} (wallet-db/parse-amount amount :ETH)]
|
||||
(fn [{:keys [db]} [_ amount symbol decimals]]
|
||||
(let [{:keys [value error]} (wallet-db/parse-amount amount symbol)]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :request-transaction :amount] (money/ether->wei value))
|
||||
(assoc-in [:wallet :request-transaction :amount] (money/formatted->internal value symbol decimals))
|
||||
(assoc-in [:wallet :request-transaction :amount-text] amount)
|
||||
(assoc-in [:wallet :request-transaction :amount-error] error))})))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet.request/set-symbol
|
||||
(fn [{:keys [db]} [_ symbol]]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :request-transaction :symbol] symbol))}))
|
||||
|
|
|
@ -19,15 +19,18 @@
|
|||
[status-im.ui.screens.wallet.components.views :as components]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.ethereum.eip681 :as eip681]
|
||||
[status-im.utils.utils :as utils]))
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.utils.ethereum.tokens :as tokens]))
|
||||
|
||||
;; Request screen
|
||||
|
||||
(views/defview send-transaction-request []
|
||||
;; TODO(jeluard) both send and request flows should be merged
|
||||
(views/letsubs [{:keys [to to-name whisper-identity]} [:wallet.send/transaction]
|
||||
{:keys [amount amount-error amount-text]} [:wallet.request/transaction]
|
||||
(views/letsubs [network [:get-current-account-network]
|
||||
{:keys [to to-name whisper-identity]} [:wallet.send/transaction]
|
||||
{:keys [amount amount-error amount-text symbol]} [:wallet.request/transaction]
|
||||
scroll (atom nil)]
|
||||
(let [{:keys [decimals] :as token} (tokens/asset-for (ethereum/network->chain-keyword network) symbol)]
|
||||
[comp/simple-screen {:avoid-keyboard? true}
|
||||
[comp/toolbar (i18n/label :t/new-request)]
|
||||
[react/view components.styles/flex
|
||||
|
@ -38,24 +41,24 @@
|
|||
:address to
|
||||
:name to-name
|
||||
:request? true}]
|
||||
[components/asset-selector {:disabled? true
|
||||
:symbol :ETH}]
|
||||
[components/asset-selector {:disabled? false
|
||||
:type :request
|
||||
:symbol symbol}]
|
||||
[components/amount-selector {:error amount-error
|
||||
:amount amount
|
||||
:amount-text amount-text
|
||||
:input-options {:max-length 21
|
||||
:on-focus (fn [] (when @scroll (utils/set-timeout #(.scrollToEnd @scroll) 100)))
|
||||
:on-change-text #(re-frame/dispatch [:wallet.request/set-and-validate-amount %])}}
|
||||
{:decimals 18
|
||||
:symbol :ETH}]]]
|
||||
:on-change-text #(re-frame/dispatch [:wallet.request/set-and-validate-amount % symbol decimals])}}
|
||||
token]]]
|
||||
[bottom-buttons/bottom-buttons styles/bottom-buttons
|
||||
nil ;; Force a phantom button to ensure consistency with other transaction screens which define 2 buttons
|
||||
[button/button {:disabled? (not (and to amount))
|
||||
:on-press #(re-frame/dispatch [:wallet-send-request whisper-identity amount])
|
||||
:on-press #(re-frame/dispatch [:wallet-send-request whisper-identity amount symbol decimals])
|
||||
:text-style {:padding-horizontal 0}
|
||||
:accessibility-label :sent-request-button}
|
||||
(i18n/label :t/send-request)
|
||||
[vector-icons/icon :icons/forward {:color :white}]]]]]))
|
||||
[vector-icons/icon :icons/forward {:color :white}]]]]])))
|
||||
|
||||
;; Main screen
|
||||
|
||||
|
|
|
@ -7,12 +7,7 @@
|
|||
(re-frame/reg-sub ::send-transaction
|
||||
:<- [:wallet]
|
||||
(fn [wallet]
|
||||
(let [transaction (:send-transaction wallet)]
|
||||
;NOTE(goranjovic): the transactions started from chat using /send command
|
||||
; are only in ether, so this parameter defaults to ETH
|
||||
(if (:symbol transaction)
|
||||
transaction
|
||||
(assoc transaction :symbol :ETH)))))
|
||||
(:send-transaction wallet)))
|
||||
|
||||
(re-frame/reg-sub :wallet.send/symbol
|
||||
:<- [::send-transaction]
|
||||
|
|
|
@ -139,10 +139,10 @@
|
|||
(when (and amount balance)
|
||||
(.greaterThanOrEqualTo balance amount)))
|
||||
|
||||
(defn usd-amount [amount-str prices]
|
||||
(defn usd-amount [amount-str from prices]
|
||||
(-> amount-str
|
||||
(js/parseFloat)
|
||||
bignumber
|
||||
(crypto->fiat (get-in prices [:ETH :USD :price]))
|
||||
(crypto->fiat (get-in prices [from :USD :price] (bignumber 0)))
|
||||
(with-precision 2)
|
||||
str))
|
||||
|
|
|
@ -50,6 +50,7 @@ class TestTransaction(SingleDeviceTestCase):
|
|||
chat_view = home_view.get_chat_with_user(recipient['username']).click()
|
||||
chat_view.commands_button.click()
|
||||
chat_view.send_command.click()
|
||||
chat_view.eth_asset.click()
|
||||
chat_view.send_as_keyevent(transaction_amount)
|
||||
wallet_view = chat_view.get_wallet_view()
|
||||
chat_view.send_message_button.click_until_presence_of_element(wallet_view.sign_in_phrase)
|
||||
|
@ -253,6 +254,7 @@ class TestTransactions(MultipleDeviceTestCase):
|
|||
one_to_one_chat_device_2.click_until_presence_of_element(device_2_chat.commands_button)
|
||||
device_1_chat.commands_button.click_until_presence_of_element(device_1_chat.request_command)
|
||||
device_1_chat.request_command.click()
|
||||
device_1_chat.eth_asset.click()
|
||||
device_1_chat.send_as_keyevent(amount)
|
||||
device_1_chat.send_message_button.click()
|
||||
device_2_chat.send_eth_to_request(amount, sender['password'], wallet_set_up=True)
|
||||
|
|
|
@ -43,6 +43,12 @@ class RequestCommand(BaseButton):
|
|||
self.locator = self.Locator.accessibility_id('request-payment-button')
|
||||
|
||||
|
||||
class EthAsset(BaseButton):
|
||||
def __init__(self, driver):
|
||||
super(EthAsset, self).__init__(driver)
|
||||
self.locator = self.Locator.text_selector('ETH')
|
||||
|
||||
|
||||
class FaucetCommand(BaseButton):
|
||||
def __init__(self, driver):
|
||||
super(FaucetCommand, self).__init__(driver)
|
||||
|
@ -200,6 +206,7 @@ class ChatView(BaseView):
|
|||
self.commands_button = CommandsButton(self.driver)
|
||||
self.send_command = SendCommand(self.driver)
|
||||
self.request_command = RequestCommand(self.driver)
|
||||
self.eth_asset = EthAsset(self.driver)
|
||||
self.faucet_command = FaucetCommand(self.driver)
|
||||
self.faucet_send_command = FaucetSendCommand(self.driver)
|
||||
|
||||
|
@ -292,6 +299,7 @@ class ChatView(BaseView):
|
|||
def send_transaction_in_1_1_chat(self, amount, password, wallet_set_up=False):
|
||||
self.commands_button.click()
|
||||
self.send_command.click()
|
||||
self.eth_asset.click()
|
||||
self.send_as_keyevent(amount)
|
||||
send_transaction_view = self.get_send_transaction_view()
|
||||
if wallet_set_up:
|
||||
|
@ -327,6 +335,7 @@ class ChatView(BaseView):
|
|||
def request_transaction_in_1_1_chat(self, amount):
|
||||
self.commands_button.click()
|
||||
self.request_command.click()
|
||||
self.eth_asset.click()
|
||||
self.send_as_keyevent(amount)
|
||||
self.send_message_button.click()
|
||||
|
||||
|
|
Loading…
Reference in New Issue