feat(dapps): Implemented hovering and proper image color for dapps item delegate. (#15408)

Enabled walletconnect qml tests.
Closes #14760
This commit is contained in:
Roman Chornii 2024-07-04 16:32:04 +03:00 committed by GitHub
parent 7146d5af5b
commit 03f8f80c56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 1238 additions and 1133 deletions

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@ import QtGraphicalEffects 1.15
import shared.controls 1.0
import shared.popups.walletconnect 1.0
import shared.popups.walletconnect.controls 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1

View File

@ -17,6 +17,7 @@ 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 shared.popups.walletconnect.controls 1.0
import AppLayouts.Wallet.controls 1.0
@ -98,6 +99,13 @@ StatusDialog {
DAppCard {
id: dappCard
afterTwoSecondsFromStatus: d.afterTwoSecondsFromStatus
isConnectedSuccessfully: d.connectionStatus === root.connectionSuccessfulStatus
isConnectionFailed: d.connectionStatus === root.connectionFailedStatus
isConnectionStarted: d.connectionStatus !== root.notConnectedStatus
isConnectionFailedOrDisconnected: d.connectionStatus !== root.connectionSuccessfulStatus
Layout.alignment: Qt.AlignHCenter
Layout.leftMargin: 12
Layout.rightMargin: Layout.leftMargin
@ -107,6 +115,11 @@ StatusDialog {
ContextCard {
Layout.fillWidth: true
accountsProxy: d.accountsProxy
selectedAccount: d.selectedAccount
selectedChains: d.selectedChains
filteredChains: d.filteredChains
notConnected: d.connectionStatus === root.notConnectedStatus
}
PermissionsCard {
@ -156,221 +169,6 @@ StatusDialog {
}
}
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
}
NetworkFilter {
id: networkFilter
Layout.preferredWidth: accountsDropdown.Layout.preferredWidth
flatNetworks: d.filteredChains
showTitle: true
multiSelection: true
selectionAllowed: d.connectionStatus === root.notConnectedStatus && d.allChainIdsAggregator.value.length > 1
selection: d.selectedChains
onSelectionChanged: {
if (d.selectedChains !== networkFilter.selection) {
d.selectedChains = networkFilter.selection
}
}
}
}
}
}
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

View File

@ -9,6 +9,7 @@ import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as StatusQ
import shared.popups.walletconnect.panels 1.0
import utils 1.0
import AppLayouts.Wallet.services.dapps.types 1.0
@ -59,11 +60,15 @@ StatusDialog {
dappName: root.dappName
dappIcon: root.dappIcon
account: root.account
userDisplayNaming: d.userDisplayNaming
}
ContentPanel {
Layout.fillWidth: true
Layout.maximumHeight: 340
payloadToDisplay: d.payloadToDisplay
}
// TODO: externalize as a TargetPanel
@ -268,11 +273,14 @@ StatusDialog {
leftButtons: ObjectModel {
MaxFeesDisplay {
maxFeesText: root.maxFeesText
feesTextColor: root.enoughFunds ? Theme.palette.directColor1 : Theme.palette.dangerColor1
}
Item {
width: 20
}
EstimatedTimeDisplay {
estimatedTimeText: root.estimatedTimeText
visible: !!root.estimatedTimeText
}
}
@ -299,191 +307,6 @@ StatusDialog {
}
}
component MaxFeesDisplay: ColumnLayout {
StatusBaseText {
text: qsTr("Max fees:")
font.pixelSize: 12
color: Theme.palette.directColor1
}
StatusBaseText {
id: maxFeesDisplay
text: root.maxFeesText
visible: !!root.maxFeesText
font.pixelSize: 16
color: root.enoughFunds ? Theme.palette.directColor1 : Theme.palette.dangerColor1
}
StatusBaseText {
text: qsTr("No fees")
visible: !maxFeesDisplay.visible
font.pixelSize: maxFeesDisplay.font.pixelSize
font.weight: maxFeesDisplay.font.weight
}
}
component EstimatedTimeDisplay: ColumnLayout {
StatusBaseText {
text: qsTr("Est. time:")
font.pixelSize: 12
color: Theme.palette.directColor1
}
StatusBaseText {
text: root.estimatedTimeText
font.pixelSize: 16
}
}
component IntentionPanel: ColumnLayout {
spacing: 8
required property string dappName
required property url dappIcon
required property var account
// Icons
Item {
Layout.fillWidth: true
Layout.preferredHeight: 40
Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: 8
StatusRoundedImage {
id: dappIconComponent
width: height
height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: -16
anchors.verticalCenter: parent.verticalCenter
image.source: root.dappIcon
}
StatusRoundIcon {
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: 16
anchors.verticalCenter: parent.verticalCenter
asset: StatusAssetSettings {
width: 24
height: 24
color: Theme.palette.primaryColor1
bgWidth: 40
bgHeight: 40
bgColor: Theme.palette.desktopBlue10
bgRadius: bgWidth / 2
bgBorderWidth: 2
bgBorderColor: Theme.palette.statusAppLayout.backgroundColor
source: "assets/sign.svg"
}
}
}
// Names and intentions
StatusBaseText {
text: qsTr("%1 wants you to %2 with %3").arg(dappName).arg(d.userDisplayNaming).arg(account.name)
Layout.preferredWidth: 400
Layout.alignment: Qt.AlignHCenter
font.pixelSize: 15
font.weight: Font.DemiBold
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
}
// TODO #14762: externalize as a InfoPill and merge base implementation with
// the existing IssuePill reusable component
Rectangle {
Layout.preferredWidth: operationStatusLayout.implicitWidth + 24
Layout.preferredHeight: operationStatusLayout.implicitHeight + 14
Layout.alignment: Qt.AlignHCenter
visible: true
border.color: Theme.palette.successColor2
border.width: 1
color: "transparent"
radius: height / 2
RowLayout {
id: operationStatusLayout
spacing: 8
anchors.centerIn: parent
StatusIcon {
Layout.preferredWidth: 16
Layout.preferredHeight: 16
visible: true
color: Theme.palette.directColor1
icon: "info"
}
StatusBaseText {
text: qsTr("Only sign if you trust the dApp")
font.pixelSize: 12
color: Theme.palette.directColor1
}
}
}
}
component ContentPanel: Rectangle {
id: contentPanelRect
border.width: 1
border.color: Theme.palette.baseColor2
color: "transparent"
radius: 8
implicitHeight: contentScrollView.implicitHeight + (2 * contentText.anchors.margins)
MouseArea {
anchors.fill: parent
cursorShape: contentScrollView.enabled || !enabled ? undefined : Qt.PointingHandCursor
enabled: contentScrollView.height < contentScrollView.contentHeight
onClicked: {
contentScrollView.enabled = !contentScrollView.enabled
}
z: contentScrollView.z + 1
}
StatusScrollView {
id: contentScrollView
anchors.fill: parent
contentWidth: availableWidth
contentHeight: contentText.contentHeight
padding: 0
enabled: false
StatusBaseText {
id: contentText
anchors.fill: parent
anchors.margins: 20
width: contentScrollView.availableWidth
text: d.payloadToDisplay
wrapMode: Text.WrapAnywhere
}
}
}
QtObject {
id: d

View File

@ -0,0 +1,88 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import StatusQ 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import AppLayouts.Wallet.controls 1.0
import shared.controls 1.0
Rectangle {
id: root
property var accountsProxy
property var selectedAccount
property var selectedChains
property var filteredChains
property bool notConnected: true
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: root.notConnected && count > 1
model: accountsProxy
onCurrentAccountChanged: root.selectedAccount = currentAccount
}
}
Rectangle {
Layout.fillWidth: true
height: 1
color: root.border.color
}
RowLayout {
Layout.margins: 16
StatusBaseText {
text: qsTr("On")
Layout.fillWidth: true
}
NetworkFilter {
id: networkFilter
Layout.preferredWidth: accountsDropdown.Layout.preferredWidth
flatNetworks: root.filteredChains
showTitle: true
multiSelection: true
selectionAllowed: notConnected && root.selectedChains.length > 1
selection: root.selectedChains
onSelectionChanged: {
if (root.selectedChains !== networkFilter.selection) {
root.selectedChains = networkFilter.selection
}
}
}
}
}
}

View File

@ -0,0 +1,137 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import StatusQ 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
ColumnLayout {
id: root
property alias name: appNameText.text
property alias url: appUrlText.text
property string iconUrl: ""
property bool afterTwoSecondsFromStatus
property bool isConnectedSuccessfully: false
property bool isConnectionFailed: true
property bool isConnectionStarted: false
property bool isConnectionFailedOrDisconnected: true
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: root.isConnectionStarted
color: root.isConnectedSuccessfully
? root.afterTwoSecondsFromStatus
? Theme.palette.successColor2
: Theme.palette.successColor3
: root.afterTwoSecondsFromStatus
? "transparent"
: Theme.palette.dangerColor3
border.color: root.isConnectedSuccessfully
? 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: root.isConnectedSuccessfully
color: Theme.palette.successColor1
}
StatusIcon {
Layout.preferredWidth: 16
Layout.preferredHeight: 16
visible: root.isConnectionFailedOrDisconnected
color: Theme.palette.dangerColor1
icon: "warning"
}
StatusBaseText {
text: {
if (root.isConnectedSuccessfully)
return qsTr("Connected. You can now go back to the dApp.")
else if (root.isConnectionFailed)
return qsTr("Error connecting to dApp. Close and try again")
return ""
}
font.pixelSize: 12
color: root.isConnectedSuccessfully ? Theme.palette.directColor1 : Theme.palette.dangerColor1
}
}
}
}

View File

@ -1,19 +1,18 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.15
import StatusQ 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
Item {
MouseArea {
id: root
implicitHeight: 50
hoverEnabled: true
required property string name
required property string url
required property string iconUrl
@ -33,7 +32,7 @@ Item {
anchors.fill: parent
source: iconUrl
source: root.iconUrl
visible: !fallbackImage.visible
}
@ -45,7 +44,7 @@ Item {
icon: "dapp"
color: Theme.palette.baseColor1
visible: iconImage.isLoading || iconImage.isError || !iconUrl
visible: iconImage.isLoading || iconImage.isError || !root.iconUrl
}
layer.enabled: true
@ -64,7 +63,7 @@ Item {
Layout.rightMargin: 12
StatusBaseText {
text: name
text: root.name
Layout.fillWidth: true
@ -76,7 +75,7 @@ Item {
clip: true
}
StatusBaseText {
text: url
text: root.url
Layout.fillWidth: true
@ -89,16 +88,17 @@ Item {
}
}
// TODO #14588 - Show tooltip on hover "Disconnect dApp"
StatusRoundButton {
implicitWidth: 32
implicitHeight: 32
radius: width / 2
StatusFlatButton {
size: StatusBaseButton.Size.Large
asset.color: root.containsMouse ? Theme.palette.directColor1
: Theme.palette.baseColor1
icon.name: "disconnect"
tooltip.text: qsTr("Disconnect dApp")
onClicked: {
console.debug(`TODO #14755 - Disconnect ${name}`)
console.debug(`TODO #14755 - Disconnect ${root.name}`)
// root.disconnectDapp()
}
}

View File

@ -0,0 +1,28 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
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
}
}

View File

@ -0,0 +1,4 @@
DAppCard 1.0 DAppCard.qml
DAppDelegate 1.0 DAppDelegate.qml
ContextCard 1.0 ContextCard.qml
PermissionsCard 1.0 PermissionsCard.qml

View File

@ -0,0 +1,53 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Rectangle {
id: root
property alias payloadToDisplay: contentText.text
border.width: 1
border.color: Theme.palette.baseColor2
color: "transparent"
radius: 8
implicitHeight: contentScrollView.implicitHeight + (2 * contentText.anchors.margins)
MouseArea {
anchors.fill: parent
cursorShape: contentScrollView.enabled || !enabled ? undefined : Qt.PointingHandCursor
enabled: contentScrollView.height < contentScrollView.contentHeight
onClicked: {
contentScrollView.enabled = !contentScrollView.enabled
}
z: contentScrollView.z + 1
}
StatusScrollView {
id: contentScrollView
anchors.fill: parent
contentWidth: availableWidth
contentHeight: contentText.contentHeight
padding: 0
enabled: false
StatusBaseText {
id: contentText
anchors.fill: parent
anchors.margins: 20
width: contentScrollView.availableWidth
text: root.payloadToDisplay
wrapMode: Text.WrapAnywhere
}
}
}

View File

@ -0,0 +1,23 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
ColumnLayout {
id: root
property alias estimatedTimeText: contentText.text
StatusBaseText {
text: qsTr("Est. time:")
font.pixelSize: 12
color: Theme.palette.directColor1
}
StatusBaseText {
id: contentText
font.pixelSize: 16
font.weight: Font.DemiBold
}
}

View File

@ -0,0 +1,110 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
ColumnLayout {
id: root
spacing: 8
required property string dappName
required property url dappIcon
required property var account
property string userDisplayNaming
// Icons
Item {
Layout.fillWidth: true
Layout.preferredHeight: 40
Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: 8
StatusRoundedImage {
width: height
height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: -16
anchors.verticalCenter: parent.verticalCenter
image.source: root.dappIcon
}
StatusRoundIcon {
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: 16
anchors.verticalCenter: parent.verticalCenter
asset: StatusAssetSettings {
width: 24
height: 24
color: Theme.palette.primaryColor1
bgWidth: 40
bgHeight: 40
bgColor: Theme.palette.desktopBlue10
bgRadius: bgWidth / 2
bgBorderWidth: 2
bgBorderColor: Theme.palette.statusAppLayout.backgroundColor
source: "assets/sign.svg"
}
}
}
// Names and intentions
StatusBaseText {
text: qsTr("%1 wants you to %2 with %3").arg(dappName).arg(root.userDisplayNaming).arg(account.name)
Layout.preferredWidth: 400
Layout.alignment: Qt.AlignHCenter
font.pixelSize: 15
font.weight: Font.DemiBold
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
}
// TODO #14762: externalize as a InfoPill and merge base implementation with
// the existing IssuePill reusable component
Rectangle {
Layout.preferredWidth: operationStatusLayout.implicitWidth + 24
Layout.preferredHeight: operationStatusLayout.implicitHeight + 14
Layout.alignment: Qt.AlignHCenter
visible: true
border.color: Theme.palette.successColor2
border.width: 1
color: "transparent"
radius: height / 2
RowLayout {
id: operationStatusLayout
spacing: 8
anchors.centerIn: parent
StatusIcon {
Layout.preferredWidth: 16
Layout.preferredHeight: 16
visible: true
color: Theme.palette.directColor1
icon: "info"
}
StatusBaseText {
text: qsTr("Only sign if you trust the dApp")
font.pixelSize: 12
color: Theme.palette.directColor1
}
}
}
}

View File

@ -0,0 +1,35 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
ColumnLayout {
id: root
property alias maxFeesText: maxFeesDisplay.text
property alias feesTextColor: maxFeesDisplay.color
StatusBaseText {
text: qsTr("Max fees:")
font.pixelSize: 12
color: Theme.palette.directColor1
}
StatusBaseText {
id: maxFeesDisplay
text: root.maxFeesText
visible: !!text
font.pixelSize: 16
}
StatusBaseText {
text: qsTr("No fees")
visible: !maxFeesDisplay.visible
font.pixelSize: maxFeesDisplay.font.pixelSize
font.weight: maxFeesDisplay.font.weight
}
}

View File

@ -0,0 +1,4 @@
MaxFeesDisplay 1.0 MaxFeesDisplay.qml
EstimatedTimeDisplay 1.0 EstimatedTimeDisplay.qml
IntentionPanel 1.0 IntentionPanel.qml
ContentPanel 1.0 ContentPanel.qml