mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-20 19:39:22 +00:00
8b4cbc59a8
The new account selector expects a generic account model. It will display all the account data if provided, including preferred chains, balance or asset balance. Otherwise it will display only the available data. The account selector can receive an initial selection based on account address and will provide the current selected address and the current selected model item. - Unify the account selector between communities and wallet - Update the account selector to work with addresses instead of model indexes - Adapt all components using the account selector or the account selection - Move/reuse qml components involved in the account selector UI - Remove nim logic used to handle index based account selection. - Adding storybook page
389 lines
10 KiB
QML
389 lines
10 KiB
QML
import QtQuick 2.15
|
|
import QtQuick.Controls 2.15
|
|
import QtQuick.Layouts 1.15
|
|
import QtQml.Models 2.14
|
|
import SortFilterProxyModel 0.2
|
|
|
|
import QtGraphicalEffects 1.15
|
|
|
|
import StatusQ 0.1
|
|
import StatusQ.Core 0.1
|
|
import StatusQ.Popups.Dialog 0.1
|
|
import StatusQ.Controls 0.1
|
|
import StatusQ.Components 0.1
|
|
import StatusQ.Core.Theme 0.1
|
|
|
|
import shared.controls 1.0
|
|
// TODO extract the components to StatusQ
|
|
import shared.popups.send.controls 1.0
|
|
|
|
import AppLayouts.Wallet.controls 1.0
|
|
|
|
import utils 1.0
|
|
|
|
StatusDialog {
|
|
id: root
|
|
|
|
width: 480
|
|
implicitHeight: d.connectionStatus === root.notConnectedStatus ? 633 : 681
|
|
|
|
required property var accounts
|
|
required property var flatNetworks
|
|
|
|
readonly property alias selectedAccount: d.selectedAccount
|
|
|
|
readonly property int notConnectedStatus: 0
|
|
readonly property int connectionSuccessfulStatus: 1
|
|
readonly property int connectionFailedStatus: 2
|
|
|
|
function openWithFilter(dappChains, proposer) {
|
|
d.connectionStatus = root.notConnectedStatus
|
|
d.afterTwoSecondsFromStatus = false
|
|
|
|
let m = proposer.metadata
|
|
dappCard.name = m.name
|
|
dappCard.url = m.url
|
|
if(m.icons.length > 0) {
|
|
dappCard.iconUrl = m.icons[0]
|
|
} else {
|
|
dappCard.iconUrl = ""
|
|
}
|
|
|
|
d.dappChains.clear()
|
|
for (let i = 0; i < dappChains.length; i++) {
|
|
// Convert to int
|
|
d.dappChains.append({ chainId: parseInt(dappChains[i]) })
|
|
}
|
|
|
|
root.open()
|
|
}
|
|
|
|
function pairSuccessful(session) {
|
|
d.connectionStatus = root.connectionSuccessfulStatus
|
|
closeAndRetryTimer.start()
|
|
}
|
|
function pairFailed(session, err) {
|
|
d.connectionStatus = root.connectionFailedStatus
|
|
closeAndRetryTimer.start()
|
|
}
|
|
|
|
Timer {
|
|
id: closeAndRetryTimer
|
|
|
|
interval: 2000
|
|
running: false
|
|
repeat: false
|
|
|
|
onTriggered: {
|
|
d.afterTwoSecondsFromStatus = true
|
|
}
|
|
}
|
|
|
|
signal connect()
|
|
signal decline()
|
|
signal disconnect()
|
|
|
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
|
|
|
title: qsTr("Connection request")
|
|
|
|
padding: 20
|
|
|
|
contentItem: ColumnLayout {
|
|
spacing: 20
|
|
clip: true
|
|
|
|
DAppCard {
|
|
id: dappCard
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
Layout.leftMargin: 12
|
|
Layout.rightMargin: Layout.leftMargin
|
|
Layout.topMargin: 20
|
|
Layout.bottomMargin: Layout.topMargin
|
|
}
|
|
|
|
ContextCard {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
PermissionsCard {
|
|
Layout.fillWidth: true
|
|
|
|
Layout.leftMargin: 12
|
|
Layout.rightMargin: Layout.leftMargin
|
|
Layout.topMargin: 20
|
|
Layout.bottomMargin: Layout.topMargin
|
|
}
|
|
}
|
|
|
|
footer: StatusDialogFooter {
|
|
id: footer
|
|
rightButtons: ObjectModel {
|
|
StatusButton {
|
|
height: 44
|
|
text: qsTr("Decline")
|
|
|
|
visible: d.connectionStatus === root.notConnectedStatus
|
|
|
|
onClicked: root.decline()
|
|
}
|
|
StatusButton {
|
|
height: 44
|
|
text: qsTr("Disconnect")
|
|
|
|
visible: d.connectionStatus === root.connectionSuccessfulStatus
|
|
|
|
type: StatusBaseButton.Type.Danger
|
|
|
|
onClicked: root.disconnect()
|
|
}
|
|
StatusButton {
|
|
height: 44
|
|
text: d.connectionStatus === root.notConnectedStatus
|
|
? qsTr("Connect")
|
|
: qsTr("Close")
|
|
|
|
onClicked: {
|
|
if (d.connectionStatus === root.notConnectedStatus)
|
|
root.connect()
|
|
else
|
|
root.close()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component ContextCard: Rectangle {
|
|
id: contextCard
|
|
|
|
implicitWidth: contextLayout.implicitWidth
|
|
implicitHeight: contextLayout.implicitHeight
|
|
|
|
radius: 8
|
|
// TODO: the color matched the design color (grey4); It is also matching the intention or we should add some another color to the theme? (e.g. sectionBorder)?
|
|
border.color: Theme.palette.baseColor2
|
|
border.width: 1
|
|
color: "transparent"
|
|
|
|
ColumnLayout {
|
|
id: contextLayout
|
|
|
|
anchors.fill: parent
|
|
|
|
RowLayout {
|
|
Layout.margins: 16
|
|
|
|
StatusBaseText {
|
|
text: qsTr("Connect with")
|
|
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
AccountSelector {
|
|
id: accountsDropdown
|
|
|
|
Layout.preferredWidth: 204
|
|
|
|
control.enabled: d.connectionStatus === root.notConnectedStatus && count > 1
|
|
model: d.accountsProxy
|
|
onCurrentAccountChanged: d.selectedAccount = currentAccount
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
height: 1
|
|
color: contextCard.border.color
|
|
}
|
|
|
|
RowLayout {
|
|
Layout.margins: 16
|
|
|
|
StatusBaseText {
|
|
text: qsTr("On")
|
|
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
// TODO: replace with a specialized network selection control
|
|
NetworkFilter {
|
|
Layout.preferredWidth: accountsDropdown.Layout.preferredWidth
|
|
|
|
flatNetworks: d.filteredChains
|
|
showAllSelectedText: false
|
|
showCheckboxes: false
|
|
enabled: d.connectionStatus === root.notConnectedStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component DAppCard: ColumnLayout {
|
|
property alias name: appNameText.text
|
|
property alias url: appUrlText.text
|
|
property string iconUrl: ""
|
|
|
|
Rectangle {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
Layout.preferredWidth: 72
|
|
Layout.preferredHeight: Layout.preferredWidth
|
|
|
|
radius: width / 2
|
|
color: Theme.palette.primaryColor3
|
|
|
|
StatusRoundedImage {
|
|
id: iconDisplay
|
|
|
|
anchors.fill: parent
|
|
|
|
visible: !fallbackImage.visible
|
|
|
|
image.source: iconUrl
|
|
}
|
|
|
|
StatusIcon {
|
|
id: fallbackImage
|
|
|
|
anchors.centerIn: parent
|
|
|
|
width: 40
|
|
height: 40
|
|
|
|
icon: "dapp"
|
|
color: Theme.palette.primaryColor1
|
|
|
|
visible: iconDisplay.image.isLoading || iconDisplay.image.isError || !iconUrl
|
|
}
|
|
}
|
|
|
|
StatusBaseText {
|
|
id: appNameText
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
Layout.bottomMargin: 4
|
|
|
|
font.bold: true
|
|
font.pixelSize: 17
|
|
}
|
|
|
|
// TODO replace with the proper URL control
|
|
StatusLinkText {
|
|
id: appUrlText
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
font.pixelSize: 15
|
|
}
|
|
|
|
Rectangle {
|
|
Layout.preferredWidth: pairingStatusLayout.implicitWidth + 32
|
|
Layout.preferredHeight: pairingStatusLayout.implicitHeight + 14
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
Layout.topMargin: 16
|
|
|
|
visible: d.connectionStatus !== root.notConnectedStatus
|
|
|
|
color: d.connectionStatus === root.connectionSuccessfulStatus
|
|
? d.afterTwoSecondsFromStatus
|
|
? Theme.palette.successColor2
|
|
: Theme.palette.successColor3
|
|
: d.afterTwoSecondsFromStatus
|
|
? "transparent"
|
|
: Theme.palette.dangerColor3
|
|
border.color: d.connectionStatus === root.connectionSuccessfulStatus
|
|
? Theme.palette.successColor2
|
|
: Theme.palette.dangerColor2
|
|
border.width: 1
|
|
radius: height / 2
|
|
|
|
RowLayout {
|
|
id: pairingStatusLayout
|
|
|
|
anchors.centerIn: parent
|
|
|
|
spacing: 8
|
|
|
|
Rectangle {
|
|
width: 6
|
|
height: 6
|
|
radius: width / 2
|
|
|
|
visible: d.connectionStatus === root.connectionSuccessfulStatus
|
|
color: Theme.palette.successColor1
|
|
}
|
|
|
|
StatusIcon {
|
|
Layout.preferredWidth: 16
|
|
Layout.preferredHeight: 16
|
|
|
|
visible: d.connectionStatus !== root.connectionSuccessfulStatus
|
|
|
|
color: Theme.palette.dangerColor1
|
|
icon: "warning"
|
|
}
|
|
|
|
StatusBaseText {
|
|
text: {
|
|
if (d.connectionStatus === root.connectionSuccessfulStatus)
|
|
return qsTr("Connected. You can now go back to the dApp.")
|
|
else if (d.connectionStatus === root.connectionFailedStatus)
|
|
return qsTr("Error connecting to dApp. Close and try again")
|
|
return ""
|
|
}
|
|
|
|
font.pixelSize: 12
|
|
color: d.connectionStatus === root.connectionSuccessfulStatus ? Theme.palette.directColor1 : Theme.palette.dangerColor1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component PermissionsCard: ColumnLayout {
|
|
spacing: 8
|
|
|
|
StatusBaseText {
|
|
text: qsTr("Uniswap Interface will be able to:")
|
|
|
|
font.pixelSize: 13
|
|
color: Theme.palette.baseColor1
|
|
}
|
|
|
|
StatusBaseText {
|
|
text: qsTr("Check your account balance and activity")
|
|
|
|
font.pixelSize: 13
|
|
}
|
|
|
|
StatusBaseText {
|
|
text: qsTr("Request transactions and message signing")
|
|
|
|
font.pixelSize: 13
|
|
}
|
|
}
|
|
|
|
QtObject {
|
|
id: d
|
|
|
|
property SortFilterProxyModel accountsProxy: SortFilterProxyModel {
|
|
sourceModel: root.accounts
|
|
|
|
sorters: RoleSorter { roleName: "position"; sortOrder: Qt.AscendingOrder }
|
|
}
|
|
|
|
property var selectedAccount: ({})
|
|
|
|
readonly property var filteredChains: LeftJoinModel {
|
|
leftModel: d.dappChains
|
|
rightModel: root.flatNetworks
|
|
|
|
joinRole: "chainId"
|
|
}
|
|
|
|
readonly property var dappChains: ListModel {}
|
|
|
|
property int connectionStatus: notConnectedStatus
|
|
property bool afterTwoSecondsFromStatus: false
|
|
}
|
|
}
|