refactor(chat): hook chat commands to qml and fix ens resolve

This commit is contained in:
Jonathan Rainville 2021-12-23 15:46:58 -05:00 committed by Sale Djenic
parent 3d4f2e26d0
commit 9016999ec2
21 changed files with 172 additions and 95 deletions

View File

@ -62,7 +62,7 @@ method requestAddressForTransaction*(self: Controller, fromAddress: string, amou
self.chatService.requestAddressForTransaction(self.chatId, fromAddress, amount, tokenAddress)
method requestTransaction*(self: Controller, fromAddress: string, amount: string, tokenAddress: string) =
self.chatService.requestAddressForTransaction(self.chatId, fromAddress, amount, tokenAddress)
self.chatService.requestTransaction(self.chatId, fromAddress, amount, tokenAddress)
method declineRequestTransaction*(self: Controller, messageId: string) =
self.chatService.declineRequestTransaction(messageId)

View File

@ -32,8 +32,12 @@ method delete*(self: Controller) =
method init*(self: Controller) =
self.events.on(SIGNAL_CONTACT_LOOKED_UP) do(e: Args):
var args = ContactArgs(e)
self.delegate.contactLookedUp(args.contactId)
var args = ResolvedContactArgs(e)
self.delegate.contactLookedUp(args.pubkey)
self.events.on(SIGNAL_ENS_RESOLVED_WITH_UUID) do(e: Args):
var args = ResolvedContactArgs(e)
self.delegate.resolvedENSWithUUID(args.address, args.uuid)
self.events.on(SIGNAL_CONTACT_ADDED) do(e: Args):
var args = ContactAddedArgs(e)
@ -83,4 +87,7 @@ method changeContactNickname*(self: Controller, publicKey: string, nickname: str
self.contactsService.changeContactNickname(publicKey, nickname)
method lookupContact*(self: Controller, value: string) =
self.contactsService.lookupContact(value)
self.contactsService.lookupContact(value)
method resolveENSWithUUID*(self: Controller, value: string, uuid: string) =
self.contactsService.resolveENSWithUUID(value, uuid)

View File

@ -42,6 +42,9 @@ method changeContactNickname*(self: AccessInterface, publicKey: string, nickname
method lookupContact*(self: AccessInterface, value: string): void {.base.} =
raise newException(ValueError, "No implementation available")
method resolveENSWithUUID*(self: AccessInterface, value: string, uuid: string): void {.base.} =
raise newException(ValueError, "No implementation available")
type
## Abstract class (concept) which must be implemented by object/s used in this
## module.

View File

@ -64,6 +64,12 @@ method lookupContact*(self: AccessInterface, value: string) {.base.} =
method contactLookedUp*(self: AccessInterface, id: string) {.base.} =
raise newException(ValueError, "No implementation available")
method resolveENSWithUUID*(self: AccessInterface, value: string, uuid: string) {.base.} =
raise newException(ValueError, "No implementation available")
method resolvedENSWithUUID*(self: AccessInterface, address: string, uuid: string) {.base.} =
raise newException(ValueError, "No implementation available")
# View Delegate Interface
# Delegate for the view must be declared here due to use of QtObject and multi
# inheritance, which is not well supported in Nim.

View File

@ -106,4 +106,10 @@ method lookupContact*(self: Module, value: string) =
self.controller.lookupContact(value)
method contactLookedUp*(self: Module, id: string) =
self.view.contactLookedUp(id)
self.view.contactLookedUp(id)
method resolveENSWithUUID*(self: Module, value: string, uuid: string) =
self.controller.resolveENSWithUUID(value, uuid)
method resolvedENSWithUUID*(self: Module, address: string, uuid: string) =
self.view.resolvedENSWithUUID(address, uuid)

View File

@ -72,6 +72,8 @@ QtObject:
proc ensWasResolved*(self: View, resolvedPubKey: string) {.signal.}
proc resolvedENSWithUUID*(self: View, resolvedAddress: string, uuid: string) {.signal.}
proc contactLookedUp*(self: View, id: string) {.slot.} =
self.ensWasResolved(id)
@ -98,6 +100,12 @@ QtObject:
self.delegate.lookupContact(value)
proc resolveENSWithUUID*(self: View, value: string, uuid: string) {.slot.} =
if value == "":
return
self.delegate.resolveENSWithUUID(value, uuid)
proc addContact*(self: View, publicKey: string) {.slot.} =
self.delegate.addContact(publicKey)

View File

@ -11,13 +11,23 @@ include ../../../app/core/tasks/common
type
LookupContactTaskArg = ref object of QObjectTaskArg
value: string
uuid: string
const lookupContactTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[LookupContactTaskArg](argEncoded)
var id = arg.value
if not id.startsWith("0x"):
id = status_ens.pubkey(id)
arg.finish(id)
var pubkey = arg.value
var address = ""
if not pubkey.startsWith("0x"):
# TODO refactor those calls to use the new backend and also do it in a signle call
pubkey = status_ens.pubkey(arg.value)
address = status_ens.address(arg.value)
let output = %*{
"id": pubkey,
"address": address,
"uuid": arg.uuid
}
arg.finish(output)
#################################################
# Async timer

View File

@ -24,6 +24,11 @@ type
ContactArgs* = ref object of Args
contactId*: string
ResolvedContactArgs* = ref object of Args
pubkey*: string
address*: string
uuid*: string
ContactNicknameUpdatedArgs* = ref object of ContactArgs
nickname*: string
@ -50,6 +55,7 @@ const IdleLimitInSeconds = int(7 * 60) # 7 minutes
# Signals which may be emitted by this service:
const SIGNAL_CONTACT_LOOKED_UP* = "SIGNAL_CONTACT_LOOKED_UP"
const SIGNAL_ENS_RESOLVED_WITH_UUID* = "SIGNAL_ENS_RESOLVED_WITH_UUID"
# Remove new when old code is removed
const SIGNAL_CONTACT_ADDED* = "new-contactAdded"
const SIGNAL_CONTACT_BLOCKED* = "new-contactBlocked"
@ -301,21 +307,36 @@ QtObject:
self.saveContact(contact)
self.events.emit(SIGNAL_CONTACT_REMOVED, ContactArgs(contactId: contact.id))
proc ensResolved*(self: Service, id: string) {.slot.} =
let data = ContactArgs(contactId: id)
self.events.emit(SIGNAL_CONTACT_LOOKED_UP, data)
proc ensResolved*(self: Service, jsonObj: string) {.slot.} =
let jsonObj = jsonObj.parseJson()
if (jsonObj["uuid"].getStr != ""):
let data = ResolvedContactArgs(
pubkey: jsonObj["id"].getStr,
address: jsonObj["address"].getStr,
uuid: jsonObj["uuid"].getStr)
self.events.emit(SIGNAL_ENS_RESOLVED_WITH_UUID, data)
else:
let data = ResolvedContactArgs(
pubkey: jsonObj["id"].getStr,
address: jsonObj["address"].getStr)
self.events.emit(SIGNAL_CONTACT_LOOKED_UP, data)
proc lookupContact*(self: Service, value: string) =
proc resolveENSWithUUID*(self: Service, value: string, uuid: string) =
if(self.closingApp):
return
let arg = LookupContactTaskArg(
tptr: cast[ByteAddress](lookupContactTask),
vptr: cast[ByteAddress](self.vptr),
slot: "ensResolved",
value: value
value: value,
uuid: uuid
)
self.threadpool.start(arg)
proc lookupContact*(self: Service, value: string) =
self.resolveENSWithUUID(value, "")
proc checkContactsStatus*(self: Service, response: string) {.slot.} =
let nowInMyLocalZone = now()
let timestampNow = uint64(nowInMyLocalZone.toTime().toUnix())

View File

@ -59,8 +59,7 @@ StatusModal {
}
return null
}
// Not Refactored Yet
// currency: root.store.walletModelInst.balanceView.defaultCurrency
currency: root.store.currentCurrency
width: stack.width
label: {
return root.isRequested ?
@ -90,9 +89,9 @@ StatusModal {
RecipientSelector {
id: selectRecipient
// Not Refactored Yet
// accounts: root.store.walletModelInst.accountsView.accounts
accounts: root.store.accounts
contacts: root.store.addedContacts
ensModule: root.store.contactsModuleInst
label: root.isRequested ?
//% "From"
qsTrId("from") :
@ -116,8 +115,6 @@ StatusModal {
AssetAndAmountInput {
id: txtAmount
selectedAccount: selectFromAccount.selectedAccount
// Not Refactored Yet
// defaultCurrency: root.store.walletModelInst.balanceView.defaultCurrency
currentCurrency: root.store.currentCurrency
// Not Refactored Yet
// getFiatValue: root.store.walletModelInst.balanceView.getFiatValue
@ -143,8 +140,7 @@ StatusModal {
asset: txtAmount.selectedAsset
amount: { "value": txtAmount.selectedAmount, "fiatValue": txtAmount.selectedFiatAmount }
toWarn: addressRequiredValidator.isWarn
// Not Refactored Yet
// currency: walletModel.balanceView.defaultCurrency
currency: root.store.currentCurrency
}
AddressRequiredValidator {
@ -179,10 +175,11 @@ StatusModal {
const validity = stack.currentGroup.validate()
if (validity.isValid && !validity.isPending) {
if (stack.isLastGroup) {
return root.sendChatCommand(selectFromAccount.selectedAccount.address,
root.sendChatCommand(selectFromAccount.selectedAccount.address,
txtAmount.selectedAmount,
txtAmount.selectedAsset.address,
txtAmount.selectedAsset.decimals)
return root.close()
}
stack.next()
}

View File

@ -129,6 +129,7 @@ StatusModal {
RecipientSelector {
id: selectRecipient
visible: false
ensModule: root.store.contactsModuleInst
// Not Refactored Yet
// accounts: root.store.walletModelInst.accountsView.accounts
contacts: root.store.addedContacts

View File

@ -186,7 +186,15 @@ QtObject {
return contactsModuleModel.isContactBlocked(pubkey)
}
function isEnsVerified(pubkey) {
return contactsModuleInst.isEnsVerified(pubkey)
}
function alias(pubkey) {
return contactsModuleModel.alias(pubkey)
return contactsModuleInst.alias(pubkey)
}
function resolveENSWithUUID(value, uuid) {
contactsModuleInst.resolveENSWithUUID(value, uuid)
}
}

View File

@ -82,21 +82,23 @@ Item {
function requestAddressForTransaction(address, amount, tokenAddress, tokenDecimals = 18) {
amount = globalUtils.eth2Wei(amount.toString(), tokenDecimals)
// Not Refactored Yet
// root.rootStore.chatsModelInst.transactions.requestAddress(activeChatId,
// address,
// amount,
// tokenAddress)
parentModule.prepareChatContentModuleForChatId(activeChatId)
let chatContentModule = parentModule.getChatContentModule()
chatContentModule.inputAreaModule.requestAddress(address,
amount,
tokenAddress)
txModalLoader.close()
}
function requestTransaction(address, amount, tokenAddress, tokenDecimals = 18) {
amount = globalUtils.eth2Wei(amount.toString(), tokenDecimals)
// Not Refactored Yet
// root.rootStore.chatsModelInst.transactions.request(activeChatId,
// address,
// amount,
// tokenAddress)
txModalLoader.close()
amount = globalUtils.eth2Wei(amount.toString(), tokenDecimals)
parentModule.prepareChatContentModuleForChatId(activeChatId)
let chatContentModule = parentModule.getChatContentModule()
chatContentModule.inputAreaModule.request(address,
amount,
tokenAddress)
}
function clickOnNotification() {
@ -194,6 +196,9 @@ Item {
model: subItems
delegate: ChatContentView {
rootStore: root.rootStore
sendTransactionNoEnsModal: cmpSendTransactionNoEns
receiveTransactionModal: cmpReceiveTransaction
sendTransactionWithEnsModal: cmpSendTransactionWithEns
Component.onCompleted: {
parentModule.prepareChatContentModuleForChatId(model.itemId)
chatContentModule = parentModule.getChatContentModule()
@ -204,6 +209,9 @@ Item {
DelegateChoice { // In all other cases
delegate: ChatContentView {
rootStore: root.rootStore
sendTransactionNoEnsModal: cmpSendTransactionNoEns
receiveTransactionModal: cmpReceiveTransaction
sendTransactionWithEnsModal: cmpSendTransactionWithEns
Component.onCompleted: {
parentModule.prepareChatContentModuleForChatId(itemId)
chatContentModule = parentModule.getChatContentModule()
@ -226,20 +234,6 @@ Item {
}
}
Loader {
id: txModalLoader
function close() {
if (!this.item) {
return
}
this.item.close()
this.closed()
}
function closed() {
this.sourceComponent = undefined
}
}
Component {
id: cmpSendTransactionNoEns
ChatCommandModal {
@ -247,7 +241,7 @@ Item {
store: root.rootStore
isContact: root.isContact
onClosed: {
txModalLoader.closed()
destroy()
}
sendChatCommand: root.requestAddressForTransaction
isRequested: false
@ -257,12 +251,13 @@ Item {
//% "Request Address"
finalButtonLabel: qsTrId("request-address")
selectRecipient.selectedRecipient: {
parentModule.prepareChatContentModuleForChatId(activeChatId)
let chatContentModule = parentModule.getChatContentModule()
return {
address: Constants.zeroAddress, // Setting as zero address since we don't have the address yet
// Not Refactored Yet
// alias: root.rootStore.chatsModelInst.channelView.activeChannel.alias,
// identicon: root.rootStore.chatsModelInst.channelView.activeChannel.identicon,
// name: root.rootStore.chatsModelInst.channelView.activeChannel.name,
alias: chatContentModule.chatDetails.name, // Do we need the alias for real or name works?
identicon: chatContentModule.chatDetails.icon,
name: chatContentModule.chatDetails.name,
type: RecipientSelector.Type.Contact
}
}
@ -278,7 +273,7 @@ Item {
store: root.rootStore
isContact: root.isContact
onClosed: {
txModalLoader.closed()
destroy()
}
sendChatCommand: root.requestTransaction
isRequested: true
@ -288,12 +283,13 @@ Item {
//% "Request"
finalButtonLabel: qsTrId("wallet-request")
selectRecipient.selectedRecipient: {
parentModule.prepareChatContentModuleForChatId(activeChatId)
let chatContentModule = parentModule.getChatContentModule()
return {
address: Constants.zeroAddress, // Setting as zero address since we don't have the address yet
// Not Refactored Yet
// alias: root.rootStore.chatsModelInst.channelView.activeChannel.alias,
// identicon: root.rootStore.chatsModelInst.channelView.activeChannel.identicon,
// name: root.rootStore.chatsModelInst.channelView.activeChannel.name,
alias: chatContentModule.chatDetails.name, // Do we need the alias for real or name works?
identicon: chatContentModule.chatDetails.icon,
name: chatContentModule.chatDetails.name,
type: RecipientSelector.Type.Contact
}
}
@ -306,22 +302,25 @@ Item {
id: cmpSendTransactionWithEns
SendModal {
id: sendTransactionWithEns
store: root.rootStore
onOpened: {
// Not Refactored Yet
// root.rootStore.walletModelInst.gasView.getGasPrice()
}
onClosed: {
txModalLoader.closed()
destroy()
}
isContact: root.isContact
selectRecipient.readOnly: true
selectRecipient.selectedRecipient: {
parentModule.prepareChatContentModuleForChatId(activeChatId)
let chatContentModule = parentModule.getChatContentModule()
return {
address: "",
// Not Refactored Yet
// alias: root.rootStore.chatsModelInst.channelView.activeChannel.alias,
// identicon: root.rootStore.chatsModelInst.channelView.activeChannel.identicon,
// name: root.rootStore.chatsModelInst.channelView.activeChannel.name,
alias: chatContentModule.chatDetails.name, // Do we need the alias for real or name works?
identicon: chatContentModule.chatDetails.icon,
name: chatContentModule.chatDetails.name,
type: RecipientSelector.Type.Contact,
ensVerified: true
}

View File

@ -31,6 +31,10 @@ ColumnLayout {
property var chatContentModule
property var rootStore
property Component sendTransactionNoEnsModal
property Component receiveTransactionModal
property Component sendTransactionWithEnsModal
StatusChatToolBar {
id: topBar
Layout.fillWidth: true
@ -345,20 +349,16 @@ ColumnLayout {
anchors.bottom: parent.bottom
recentStickers: chatContentRoot.rootStore.stickersModuleInst.recent
stickerPackList: chatContentRoot.rootStore.stickersModuleInst.stickerPacks
// chatType: chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.chatType
chatType: chatContentModule.chatDetails.type
onSendTransactionCommandButtonClicked: {
// Not Refactored Yet
// if (chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.ensVerified) {
// txModalLoader.sourceComponent = cmpSendTransactionWithEns
// } else {
// txModalLoader.sourceComponent = cmpSendTransactionNoEns
// }
// txModalLoader.item.open()
if (chatContentRoot.rootStore.isEnsVerified(chatContentModule.getMyChatId())) {
Global.openPopup(chatContentRoot.sendTransactionWithEnsModal)
} else {
Global.openPopup(chatContentRoot.sendTransactionNoEnsModal)
}
}
onReceiveTransactionCommandButtonClicked: {
// Not Refactored Yet
// txModalLoader.sourceComponent = cmpReceiveTransaction
// txModalLoader.item.open()
Global.openPopup(chatContentRoot.receiveTransactionModal)
}
onStickerSelected: {
chatContentRoot.rootStore.sendSticker(chatContentModule.getMyChatId(),

View File

@ -22,8 +22,7 @@ Item {
property string invalidInputErrorMessage: qsTrId("this-needs-to-be-a-number")
//% "Please enter an amount"
property string noInputErrorMessage: qsTrId("please-enter-an-amount")
property string defaultCurrency: "USD"
property string currentCurrency: ""
property string currentCurrency: "USD"
property alias selectedFiatAmount: txtFiatBalance.text
property alias selectedAmount: inputAmount.text
property var selectedAccount
@ -122,7 +121,7 @@ Item {
}
onClicked: {
inputAmount.text = Utils.stripTrailingZeros(selectAsset.selectedAsset.value)
txtFiatBalance.text = root.getFiatValue(inputAmount.text, selectAsset.selectedAsset.symbol, root.defaultCurrency)
txtFiatBalance.text = root.getFiatValue(inputAmount.text, selectAsset.selectedAsset.symbol, root.currentCurrency)
}
}
}
@ -158,7 +157,7 @@ Item {
if (amount === "") {
txtFiatBalance.text = "0.00"
} else {
txtFiatBalance.text = root.getFiatValue(amount, selectAsset.selectedAsset.symbol, root.defaultCurrency)
txtFiatBalance.text = root.getFiatValue(amount, selectAsset.selectedAsset.symbol, root.currentCurrency)
}
}
onTextChanged: {
@ -190,7 +189,7 @@ Item {
if (inputAmount.text === "" || isNaN(inputAmount.text)) {
return
}
txtFiatBalance.text = root.getFiatValue(inputAmount.text, selectAsset.selectedAsset.symbol, root.defaultCurrency)
txtFiatBalance.text = root.getFiatValue(inputAmount.text, selectAsset.selectedAsset.symbol, root.currentCurrency)
root.validate(true)
}
}
@ -220,13 +219,13 @@ Item {
if (balance === "" || isNaN(balance)) {
return
}
inputAmount.text = root.getCryptoValue(balance, root.defaultCurrency, selectAsset.selectedAsset.symbol)
inputAmount.text = root.getCryptoValue(balance, root.currentCurrency, selectAsset.selectedAsset.symbol)
}
}
StyledText {
id: txtFiatSymbol
text: root.defaultCurrency.toUpperCase()
text: root.currentCurrency.toUpperCase()
font.weight: Font.Medium
font.pixelSize: 12
color: Style.current.secondaryText

View File

@ -18,6 +18,7 @@ Item {
id: root
property var contacts
property var selectedContact
property var ensModule
height: select.height
property int dropdownWidth: width
//% "Please select a contact"
@ -25,6 +26,7 @@ Item {
property alias validationErrorAlignment: select.validationErrorAlignment
property bool isValid: false
property alias isPending: ensResolver.isPending
property bool readOnly: false
property bool isResolvedAddress: false
//% "Select a contact"
@ -143,6 +145,7 @@ Item {
anchors.right: select.right
anchors.topMargin: Style.current.halfPadding
debounceDelay: 0
ensModule: root.ensModule
onResolved: {
root.isResolvedAddress = true
var selectedContact = root.selectedContact

View File

@ -15,6 +15,7 @@ Item {
property var accounts
property var contacts
property int currentIndex
property var ensModule
property int inputWidth: 272
property int sourceSelectWidth: 136
property alias label: txtLabel.text
@ -174,6 +175,7 @@ Item {
dropdownWidth: parent.width
readOnly: root.readOnly
isContact: root.isContact
ensModule: root.ensModule
Layout.preferredWidth: selAddressSource.visible ? root.inputWidth : parent.width
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true

View File

@ -113,6 +113,7 @@ ModalPopup {
accounts: root.store.accounts
contacts: root.store.addedContacts
currentIndex: index
ensModule: root.store.contactsModuleInst
//% "Recipient"
label: qsTrId("recipient")
anchors.top: separator.bottom

View File

@ -129,6 +129,7 @@ StatusModal {
RecipientSelector {
id: selectRecipient
visible: false
ensModule: root.store.contactsModuleInst
// Not Refactored Yet
// accounts: root.store.walletModelInst.accountsView.accounts
// Not Refactored Yet

View File

@ -108,6 +108,7 @@ ModalPopup {
id: selectRecipient
visible: false
// Not Refactored Yet
// ensModule: root.store.contactsModuleInst
// accounts: RootStore.walletModelInst.accountsView.accounts
contacts: RootStore.contactsModuleInst.model.addedContacts
selectedRecipient: { "address": RootStore.utilsModelInst.ensRegisterAddress, "type": RecipientSelector.Type.Address }

View File

@ -112,6 +112,7 @@ ModalPopup {
id: selectRecipient
visible: false
// Not Refactored Yet
// ensModule: root.store.contactsModuleInst
// accounts: RootStore.walletModelInst.accountsView.accounts
contacts: RootStore.contactsModuleInst.model.addedContacts
selectedRecipient: { "address": contractAddress, "type": RecipientSelector.Type.Address }

View File

@ -12,11 +12,12 @@ Item {
property bool isPending: false
readonly property string uuid: Utils.uuid()
property int debounceDelay: 600
property var ensModule
readonly property var validateAsync: Backpressure.debounce(inpAddress, debounceDelay, function (inputValue) {
root.isPending = true
var name = inputValue.startsWith("@") ? inputValue.substring(1) : inputValue
// Not Refactored Yet
// RootStore.chatsModelInst.ensView.resolveENSWithUUID(name, uuid)
root.ensModule.resolveENSWithUUID(name, uuid)
});
signal resolved(string resolvedAddress)
@ -41,14 +42,16 @@ Item {
height: root.height
}
}
// Connections {
// target: RootStore.chatsModelInst.ensView
// onEnsWasResolved: {
// if (uuid !== root.uuid) {
// return
// }
// root.isPending = false
// root.resolved(resolvedAddress)
// }
// }
Connections {
enabled: !!root.ensModule
target: root.ensModule
onResolvedENSWithUUID: {
if (uuid !== root.uuid) {
return
}
root.isPending = false
root.resolved(resolvedAddress)
}
}
}