diff --git a/src/app/wallet/view.nim b/src/app/wallet/view.nim index c8f31fc2f0..d2d9bcb4c5 100644 --- a/src/app/wallet/view.nim +++ b/src/app/wallet/view.nim @@ -14,6 +14,7 @@ QtObject: currentAssetList*: AssetList currentCollectiblesLists*: CollectiblesList currentAccount: AccountItemView + focusedAccount: AccountItemView currentTransactions: TransactionList defaultTokenList: TokenList status: Status @@ -31,6 +32,7 @@ QtObject: self.accounts.delete self.currentAssetList.delete self.currentAccount.delete + self.focusedAccount.delete self.currentTransactions.delete self.defaultTokenList.delete self.QAbstractListModel.delete @@ -43,6 +45,7 @@ QtObject: result.status = status result.accounts = newAccountList() result.currentAccount = newAccountItemView() + result.focusedAccount = newAccountItemView() result.currentAssetList = newAssetList() result.currentTransactions = newTransactionList() result.currentCollectiblesLists = newCollectiblesList() @@ -142,6 +145,26 @@ QtObject: write = setCurrentAccountByIndex notify = currentAccountChanged + proc focusedAccountChanged*(self: WalletView) {.signal.} + + proc setFocusedAccountByAddress*(self: WalletView, address: string) {.slot.} = + if(self.accounts.rowCount() == 0): return + + let index = self.accounts.getAccountindexByAddress(address) + if index == -1: return + let selectedAccount = self.accounts.getAccount(index) + if self.focusedAccount.address == selectedAccount.address: return + self.focusedAccount.setAccountItem(selectedAccount) + self.focusedAccountChanged() + + proc getFocusedAccount*(self: WalletView): QVariant {.slot.} = + result = newQVariant(self.focusedAccount) + + QtProperty[QVariant] focusedAccount: + read = getFocusedAccount + write = setFocusedAccountByAddress + notify = focusedAccountChanged + proc currentAssetListChanged*(self: WalletView) {.signal.} proc getCurrentAssetList(self: WalletView): QVariant {.slot.} = @@ -248,21 +271,6 @@ QtObject: proc defaultCurrency*(self: WalletView): string {.slot.} = self.status.wallet.getDefaultCurrency() - proc getAccountValueByAddress*(self: WalletView, address: string, arg: string): string {.slot.} = - let index = self.accounts.getAccountindexByAddress(address) - if index == -1: return - let account = self.accounts.getAccount(index) - case arg: - of "name": result = account.name - of "iconColor": result = account.iconColor - of "balance": result = account.balance - of "path": result = account.path - of "walletType": result = account.walletType - of "publicKey": result = account.publicKey - of "realFiatBalance": result = $account.realFiatBalance - of "wallet": result = $account.wallet - of "chat": result = $account.wallet - proc defaultCurrencyChanged*(self: WalletView) {.signal.} proc setDefaultCurrency*(self: WalletView, currency: string) {.slot.} = diff --git a/src/status/wallet/balance_manager.nim b/src/status/wallet/balance_manager.nim index ddca4f7ac3..7d930ff741 100644 --- a/src/status/wallet/balance_manager.nim +++ b/src/status/wallet/balance_manager.nim @@ -28,8 +28,7 @@ proc getPrice(crypto: string, fiat: string): string = let response = client.request(url) result = $parseJson(response.body)[fiat.toUpper] except Exception as e: - echo "error getting price" - echo e.msg + error "Error getting price", message = e.msg result = "0.0" proc getEthBalance(address: string): string = diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandModal.qml b/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandModal.qml index 46bf93488a..36b9b371a6 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandModal.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandModal.qml @@ -10,6 +10,7 @@ ModalPopup { property string commandTitle: "Send" property string finalButtonLabel: "Request address" property var sendChatCommand: function () {} + property bool isRequested: false id: root title: root.commandTitle @@ -82,6 +83,7 @@ ModalPopup { defaultCurrency: walletModel.defaultCurrency getFiatValue: walletModel.getFiatValue getCryptoValue: walletModel.getCryptoValue + isRequested: root.isRequested width: stack.width reset: function() { selectedAccount = Qt.binding(function() { return selectFromAccount.selectedAccount }) @@ -147,8 +149,7 @@ ModalPopup { anchors.fill: parent border.width: 0 radius: width / 2 - color: btnBack.disabled ? Style.current.grey : - btnBack.hovered ? Qt.darker(btnBack.btnColor, 1.1) : btnBack.btnColor + color: btnBack.hovered ? Qt.darker(btnBack.btnColor, 1.1) : btnBack.btnColor SVGImage { width: 20.42 @@ -176,7 +177,8 @@ ModalPopup { if (stack.isLastGroup) { return root.sendChatCommand(selectFromAccount.selectedAccount.address, txtAmount.selectedAmount, - txtAmount.selectedAsset.address) + txtAmount.selectedAsset.address, + txtAmount.selectedAsset.decimals) } stack.next() } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandsPopup.qml b/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandsPopup.qml index f5aaaaa143..a8d6a24472 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandsPopup.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandsPopup.qml @@ -26,6 +26,23 @@ Popup { } } + function requestAddressForTransaction(address, amount, tokenAddress, tokenDecimals = 18) { + amount = Utils.multiplyByDecimals(amount, tokenDecimals) + chatsModel.requestAddressForTransaction(chatsModel.activeChannel.id, + address, + amount, + tokenAddress) + chatCommandModal.close() + } + function requestTransaction(address, amount, tokenAddress, tokenDecimals = 18) { + amount = Utils.multiplyByDecimals(amount, tokenDecimals) + chatsModel.requestTransaction(chatsModel.activeChannel.id, + address, + amount, + tokenAddress) + chatCommandModal.close() + } + Row { id: buttonRow anchors.left: parent.left @@ -35,12 +52,15 @@ Popup { padding: Style.current.halfPadding spacing: Style.current.halfPadding + ChatCommandButton { iconColor: Style.current.purple iconSource: "../../../../img/send.svg" //% "Send transaction" text: qsTrId("send-transaction") onClicked: function () { + chatCommandModal.sendChatCommand = root.requestAddressForTransaction + chatCommandModal.isRequested = false chatCommandModal.commandTitle = qsTr("Send") chatCommandModal.title = chatCommandModal.commandTitle chatCommandModal.finalButtonLabel = qsTr("Request Address") @@ -50,18 +70,12 @@ Popup { name: chatsModel.activeChannel.name, type: RecipientSelector.Type.Contact } - chatCommandModal.sendChatCommand = function(address, amount, tokenAddress) { - chatsModel.requestAddressForTransaction(chatsModel.activeChannel.id, - address, - amount, - tokenAddress) - chatCommandModal.close() - } chatCommandModal.open() root.close() } } + ChatCommandButton { iconColor: Style.current.orange iconSource: "../../../../img/send.svg" @@ -69,6 +83,8 @@ Popup { //% "Request transaction" text: qsTrId("request-transaction") onClicked: function () { + chatCommandModal.sendChatCommand = root.requestTransaction + chatCommandModal.isRequested = true chatCommandModal.commandTitle = qsTr("Request") chatCommandModal.title = chatCommandModal.commandTitle chatCommandModal.finalButtonLabel = qsTr("Request") @@ -78,13 +94,6 @@ Popup { name: chatsModel.activeChannel.name, type: RecipientSelector.Type.Contact } - chatCommandModal.sendChatCommand = function(address, amount, tokenAddress) { - chatsModel.requestTransaction(chatsModel.activeChannel.id, - address, - amount, - tokenAddress) - chatCommandModal.close() - } chatCommandModal.open() root.close() } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml b/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml index ff9eadfa14..506b641873 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml @@ -12,8 +12,6 @@ ModalPopup { property var selectedAsset property var selectedAmount property var selectedFiatAmount - property var selectedGasLimit - property var selectedGasPrice id: root @@ -53,11 +51,11 @@ ModalPopup { let response = JSON.parse(responseStr) if (response.error) { - if (response.error.includes("could not decrypt key with given password")){ + if (response.error.message.includes("could not decrypt key with given password")){ transactionSigner.validationError = qsTr("Wrong password") return } - sendingError.text = response.error + sendingError.text = response.error.message return sendingError.open() } @@ -93,6 +91,18 @@ ModalPopup { fastestGasPrice = Qt.binding(function(){ return parseFloat(walletModel.fastestGasPrice) }) } } + GasValidator { + id: gasValidator + anchors.bottom: parent.bottom + anchors.bottomMargin: 8 + selectedAccount: root.selectedAccount + selectedAmount: parseFloat(root.selectedAmount) + selectedAsset: root.selectedAsset + selectedGasEthValue: gasSelector.selectedGasEthValue + reset: function() { + selectedGasEthValue = Qt.binding(function() { return gasSelector.selectedGasEthValue }) + } + } } TransactionFormGroup { id: group2 @@ -104,15 +114,23 @@ ModalPopup { width: stack.width fromAccount: root.selectedAccount gas: { - const value = walletModel.getGasEthValue(gasSelector.selectedGasPrice, gasSelector.selectedGasLimit) - const fiatValue = walletModel.getFiatValue(value, "ETH", walletModel.defaultCurrency) - return { value, "symbol": "ETH", fiatValue } + "value": gasSelector.selectedGasEthValue, + "symbol": "ETH", + "fiatValue": gasSelector.selectedGasFiatValue } toAccount: root.selectedRecipient asset: root.selectedAsset amount: { "value": root.selectedAmount, "fiatValue": root.selectedFiatAmount } currency: walletModel.defaultCurrency - reset: function() {} + reset: function() { + gas = Qt.binding(function() { + return { + "value": gasSelector.selectedGasEthValue, + "symbol": "ETH", + "fiatValue": gasSelector.selectedGasFiatValue + } + }) + } } } TransactionFormGroup { @@ -146,8 +164,7 @@ ModalPopup { anchors.fill: parent border.width: 0 radius: width / 2 - color: btnBack.disabled ? Style.current.grey : - btnBack.hovered ? Qt.darker(btnBack.btnColor, 1.1) : btnBack.btnColor + color: btnBack.hovered ? Qt.darker(btnBack.btnColor, 1.1) : btnBack.btnColor SVGImage { width: 20.42 diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml index 45bf81a107..fda5ed72bc 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml @@ -28,6 +28,14 @@ Item { anchors.fill: parent cursorShape: Qt.PointingHandCursor onClicked: { + walletModel.setFocusedAccountByAddress(commandParametersObject.fromAddress) + var acc = walletModel.focusedAccount + signTransactionModal.selectedAccount = { + name: acc.name, + address: commandParametersObject.fromAddress, + iconColor: acc.iconColor, + assets: acc.assets + } signTransactionModal.open() } } @@ -38,13 +46,7 @@ Item { onOpened: { walletModel.getGasPricePredictions() } - selectedAccount: { - return { - name: walletModel.getAccountValueByAddress(commandParametersObject.fromAddress, 'name'), - address: commandParametersObject.fromAddress, - iconColor: walletModel.getAccountValueByAddress(commandParametersObject.fromAddress, 'iconColor') - } - } + selectedAccount: {} selectedRecipient: { return { address: commandParametersObject.address, @@ -54,7 +56,7 @@ Item { } } selectedAsset: { - return { + return { name: token.name, symbol: token.symbol, address: commandParametersObject.contract diff --git a/ui/nim-status-client.pro b/ui/nim-status-client.pro index 97c06892b8..e397f4d1c9 100644 --- a/ui/nim-status-client.pro +++ b/ui/nim-status-client.pro @@ -343,6 +343,7 @@ DISTFILES += \ shared/NotificationWindow.qml \ shared/PopupMenu.qml \ shared/Identicon.qml \ + shared/AssetAndAmountInput.qml \ shared/CopyToClipBoardButton.qml \ shared/GasSelector.qml \ shared/RoundedImage.qml \ diff --git a/ui/shared/AssetAndAmountInput.qml b/ui/shared/AssetAndAmountInput.qml index 38b7eea4d1..d4ae3ed6c7 100644 --- a/ui/shared/AssetAndAmountInput.qml +++ b/ui/shared/AssetAndAmountInput.qml @@ -21,7 +21,8 @@ Item { property var getFiatValue: function () {} property var getCryptoValue: function () {} property bool isDirty: false - property bool isValid: true + property bool isRequested: false + property bool isValid: false property var reset: function() {} function resetInternal() { @@ -31,7 +32,7 @@ Item { inputAmount.resetInternal() txtBalanceDesc.color = Style.current.secondaryText txtBalance.color = Qt.binding(function() { return txtBalance.hovered ? Style.current.textColor : Style.current.secondaryText }) - isValid = true + isValid = false } id: root @@ -41,8 +42,6 @@ Item { anchors.left: parent.left function validate(checkDirty) { - // TODO remove me - return true let isValid = true let error = "" const hasTyped = checkDirty ? isDirty : true @@ -58,7 +57,7 @@ Item { } else if (input === 0.00 && hasTyped) { error = greaterThan0ErrorMessage isValid = false - } else if (input > balance && !noInput) { + } else if (!isRequested && input > balance && !noInput) { error = balanceErrorMessage isValid = false } @@ -87,6 +86,7 @@ Item { } Item { + visible: !root.isRequested anchors.right: parent.right anchors.left: parent.left anchors.top: parent.top