status-desktop/ui/app/AppLayouts/Profile/views/EnsView.qml

484 lines
16 KiB
QML

import QtQuick 2.14
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.14
import QtQml.StateMachine 1.14 as DSM
import StatusQ 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Popups.Dialog 0.1
import StatusQ.Core.Theme 0.1
import utils 1.0
import shared 1.0
import shared.stores 1.0 as SharedStores
import shared.popups.send 1.0
import AppLayouts.Wallet.stores 1.0
import "../stores"
Item {
id: ensView
property EnsUsernamesStore ensUsernamesStore
property WalletAssetsStore walletAssetsStore
required property var sendModalPopup
property ContactsStore contactsStore
property SharedStores.NetworkConnectionStore networkConnectionStore
property int profileContentWidth
property bool showSearchScreen: false
property string addedUsername: ""
property string selectedUsername: ""
property string selectedChainId: ""
signal next(output: string)
signal back()
signal done(ensUsername: string)
signal connect(ensUsername: string)
signal changePubKey(ensUsername: string)
signal goToWelcome();
signal goToList();
Layout.fillHeight: true
Layout.fillWidth: true
clip: true
QtObject {
id: d
readonly property string registerENS: "RegisterENS"
readonly property string setPubKey: "SetPubKey"
readonly property string releaseENS: "ReleaseENS"
readonly property var sntToken: ModelUtils.getByKey(ensView.walletAssetsStore.groupedAccountAssetsModel, "tokensKey", ensView.ensUsernamesStore.getStatusTokenKey())
readonly property SumAggregator aggregator: SumAggregator {
model: !!d.sntToken && !!d.sntToken.balances ? d.sntToken.balances: nil
roleName: "balance"
}
property real sntBalance: !!sntToken && !!sntToken.decimals ? aggregator.value/(10 ** sntToken.decimals): 0
}
DSM.StateMachine {
id: stateMachine
initialState: ensView.ensUsernamesStore.ensUsernamesModel.count > 0 ? listState : welcomeState
running: true
DSM.State {
id: welcomeState
onEntered: loader.sourceComponent = welcome
DSM.SignalTransition {
targetState: searchState
signal: next
}
DSM.SignalTransition {
targetState: listState
signal: goToList
}
}
DSM.State {
id: searchState
onEntered: loader.sourceComponent = search
DSM.SignalTransition {
targetState: tAndCState
signal: next
guard: output === "available"
}
DSM.SignalTransition {
targetState: addedState
signal: connect
}
DSM.SignalTransition {
targetState: listState
signal: goToList
}
DSM.SignalTransition {
targetState: welcomeState
signal: goToWelcome
}
DSM.SignalTransition {
targetState: ensConnectedState
signal: done
}
}
DSM.State {
id: addedState
onEntered: {
loader.sourceComponent = added;
loader.item.ensUsername = addedUsername;
}
DSM.SignalTransition {
targetState: listState
signal: next
}
DSM.SignalTransition {
targetState: listState
signal: goToList
}
DSM.SignalTransition {
targetState: welcomeState
signal: goToWelcome
}
}
DSM.State {
id: listState
onEntered: {
loader.sourceComponent = list;
}
DSM.SignalTransition {
targetState: searchState
signal: next
guard: output === "search"
}
DSM.SignalTransition {
targetState: detailsState
signal: next
guard: output === "details"
}
DSM.SignalTransition {
targetState: listState
signal: goToList
}
DSM.SignalTransition {
targetState: welcomeState
signal: goToWelcome
}
}
DSM.State {
id: detailsState
onEntered: {
loader.sourceComponent = details;
}
DSM.SignalTransition {
targetState: listState
signal: back
}
DSM.SignalTransition {
targetState: listState
signal: goToList
}
DSM.SignalTransition {
targetState: welcomeState
signal: goToWelcome
}
DSM.SignalTransition {
targetState: ensReleasedState
signal: done
}
}
DSM.State {
id: tAndCState
onEntered:loader.sourceComponent = termsAndConditions
DSM.SignalTransition {
targetState: listState
signal: goToList
}
DSM.SignalTransition {
targetState: welcomeState
signal: goToWelcome
}
DSM.SignalTransition {
targetState: listState
signal: back
}
DSM.SignalTransition {
targetState: listState
signal: back
}
DSM.SignalTransition {
targetState: ensRegisteredState
signal: done
}
}
DSM.State {
id: ensRegisteredState
onEntered:loader.sourceComponent = ensRegistered
DSM.SignalTransition {
targetState: listState
signal: next
}
}
DSM.State {
id: ensReleasedState
onEntered:loader.sourceComponent = ensReleased
DSM.SignalTransition {
targetState: listState
signal: next
}
}
DSM.State {
id: ensConnectedState
onEntered:loader.sourceComponent = ensConnected
DSM.SignalTransition {
targetState: listState
signal: next
}
}
}
Loader {
id: loader
anchors.fill: parent
}
Component {
id: welcome
EnsWelcomeView {
username: ensView.ensUsernamesStore.username
onStartBtnClicked: next(null)
profileContentWidth: ensView.profileContentWidth
startButtonEnabled: ensView.networkConnectionStore.ensNetworkAvailable
tooltipText: ensView.networkConnectionStore.ensNetworkUnavailableText
}
}
Component {
id: search
EnsSearchView {
ensUsernamesStore: ensView.ensUsernamesStore
profileContentWidth: ensView.profileContentWidth
onContinueClicked: {
if(output === "connected"){
connect(username)
} else {
selectedUsername = username;
next(output);
}
}
onConnectUsername: {
ensView.selectedUsername = username
ensView.sendModalPopup.modalHeaderText = qsTr("Connect username with your pubkey")
ensView.sendModalPopup.interactive = false
ensView.sendModalPopup.preSelectedRecipient = ensView.ensUsernamesStore.getEnsRegisteredAddress()
ensView.sendModalPopup.preSelectedRecipientType = Helpers.RecipientAddressObjectType.Address
ensView.sendModalPopup.preSelectedHoldingID = Constants.ethToken
ensView.sendModalPopup.preSelectedHoldingType = Constants.TokenType.ERC20
ensView.sendModalPopup.preSelectedSendType = Constants.SendType.ENSSetPubKey
ensView.sendModalPopup.preDefinedAmountToSend = LocaleUtils.numberToLocaleString(0)
ensView.sendModalPopup.preSelectedChainId = ensView.selectedChainId
ensView.sendModalPopup.publicKey = ensView.contactsStore.myPublicKey
ensView.sendModalPopup.ensName = ensView.selectedUsername
ensView.sendModalPopup.open()
}
Connections {
target: ensView.ensUsernamesStore.ensUsernamesModule
function onTransactionWasSent(trxType: string, chainId: int, txHash: string, username: string, error: string) {
if (!!error || trxType !== d.setPubKey) {
return
}
done(ensView.selectedUsername)
}
}
}
}
Component {
id: termsAndConditions
EnsTermsAndConditionsView {
ensUsernamesStore: ensView.ensUsernamesStore
username: selectedUsername
onBackBtnClicked: back();
onRegisterUsername: {
ensView.sendModalPopup.interactive = false
ensView.sendModalPopup.preSelectedRecipient = ensView.ensUsernamesStore.getEnsRegisteredAddress()
ensView.sendModalPopup.preSelectedRecipientType = Helpers.RecipientAddressObjectType.Address
ensView.sendModalPopup.preSelectedHoldingID = !!d.sntToken && !!d.sntToken.symbol ? d.sntToken.symbol: ""
ensView.sendModalPopup.preSelectedHoldingType = Constants.TokenType.ERC20
ensView.sendModalPopup.preSelectedSendType = Constants.SendType.ENSRegister
ensView.sendModalPopup.preDefinedAmountToSend = LocaleUtils.numberToLocaleString(10)
ensView.sendModalPopup.preSelectedChainId = ensView.selectedChainId
ensView.sendModalPopup.publicKey = ensView.contactsStore.myPublicKey
ensView.sendModalPopup.ensName = ensView.selectedUsername
ensView.sendModalPopup.open()
}
Connections {
target: ensView.ensUsernamesStore.ensUsernamesModule
function onTransactionWasSent(trxType: string, chainId: int, txHash: string, username: string, error: string) {
if (!!error || trxType !== d.registerENS) {
return
}
done(ensView.selectedUsername)
}
}
}
}
Component {
id: added
EnsAddedView {
onOkBtnClicked: next(null)
}
}
Component {
id: ensRegistered
EnsRegisteredView {
ensUsername: selectedUsername
onOkBtnClicked: next(null)
}
}
Component {
id: ensReleased
EnsReleasedView {
ensUsername: selectedUsername
onOkBtnClicked: next(null)
}
}
Component {
id: ensConnected
EnsConnectedView {
ensUsername: selectedUsername
onOkBtnClicked: next(null)
}
}
Component {
id: list
EnsListView {
ensUsernamesStore: ensView.ensUsernamesStore
profileContentWidth: ensView.profileContentWidth
onAddBtnClicked: next("search")
onSelectEns: {
ensView.ensUsernamesStore.ensDetails(chainId, username)
selectedUsername = username
selectedChainId = chainId
next("details")
}
}
}
Component {
id: details
EnsDetailsView {
ensUsernamesStore: ensView.ensUsernamesStore
username: selectedUsername
chainId: selectedChainId
onBackBtnClicked: back()
onReleaseUsernameRequested: {
const name = RootStore.getNameForWalletAddress(senderAddress)
if (name === "") {
Global.openPopup(noAccountPopupComponent)
return
}
ensView.sendModalPopup.modalHeaderText = qsTr("Release your username")
ensView.sendModalPopup.interactive = false
ensView.sendModalPopup.preSelectedAccountAddress = senderAddress
ensView.sendModalPopup.preSelectedRecipient = ensView.ensUsernamesStore.getEnsRegisteredAddress()
ensView.sendModalPopup.preSelectedRecipientType = Helpers.RecipientAddressObjectType.Address
ensView.sendModalPopup.preSelectedHoldingID = Constants.ethToken
ensView.sendModalPopup.preSelectedHoldingType = Constants.TokenType.Native
ensView.sendModalPopup.preSelectedSendType = Constants.SendType.ENSRelease
ensView.sendModalPopup.preDefinedAmountToSend = LocaleUtils.numberToLocaleString(0)
ensView.sendModalPopup.preSelectedChainId = ensView.selectedChainId
ensView.sendModalPopup.publicKey = ensView.contactsStore.myPublicKey
ensView.sendModalPopup.ensName = ensView.selectedUsername
ensView.sendModalPopup.open()
}
Connections {
target: ensView.ensUsernamesStore.ensUsernamesModule
function onTransactionWasSent(trxType: string, chainId: int, txHash: string, username: string, error: string) {
if (!!error || trxType !== d.releaseENS) {
return
}
done(ensView.selectedUsername)
}
}
}
}
Component {
id: noAccountPopupComponent
StatusDialog {
title: qsTr("Release username")
StatusBaseText {
anchors.fill: parent
font.pixelSize: Constants.keycard.general.fontSize2
color: Theme.palette.directColor1
text: qsTr("The account this username was bought with is no longer among active accounts.\nPlease add it and try again.")
}
standardButtons: Dialog.Ok
}
}
Connections {
target: ensView
function onConnect(ensUsername: string) {
addedUsername = ensUsername;
}
}
Connections {
target: ensView.ensUsernamesStore.ensUsernamesModule
function onTransactionCompleted(success: bool, txHash: string, username: string, trxType: string) {
let title = ""
switch(trxType){
case d.registerENS:
title = !success ?
qsTr("ENS Registration failed")
:
qsTr("ENS Registration completed");
break;
case d.setPubKey:
title = !success ?
qsTr("Updating ENS pubkey failed")
:
qsTr("Updating ENS pubkey completed");
break;
case d.releaseENS:
title = !success ?
qsTr("Releasing ENS name failed")
:
qsTr("ENS name released");
break
default:
console.error("unknown transaction type: ", trxType);
return
}
let icon = "block-icon";
let ephType = Constants.ephemeralNotificationType.normal;
if (success) {
icon = "check-circle";
ephType = Constants.ephemeralNotificationType.success;
}
let url = `${ensView.ensUsernamesStore.getEtherscanTxLink()}/${txHash}`;
Global.displayToastMessage(qsTr("Transaction pending..."),
qsTr("View on etherscan"),
icon,
false,
ephType,
url)
}
}
}