chore(dapps) move dApps UX into its own DAppsWorkflow component

Storybook: also automate related workflows for faster iteration

Also extend the inspector utils to handle Loaders and Popups

Updates: #14607
This commit is contained in:
Stefan 2024-05-06 19:55:11 +02:00 committed by Stefan Dunca
parent 78775d3d69
commit 7cd97a0051
11 changed files with 333 additions and 211 deletions

View File

@ -1,13 +0,0 @@
import QtQuick 2.15
import shared.popups.walletconnect 1.0
Item {
id: root
ConnectDappModal {
id: dappModal
visible: true
}
}

View File

@ -1,92 +0,0 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQml 2.15
import Qt.labs.settings 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Popups.Dialog 0.1
import Models 1.0
import Storybook 1.0
import AppLayouts.Wallet.controls 1.0
import AppLayouts.Wallet.services.dapps 1.0
import SortFilterProxyModel 0.2
import shared.popups.walletconnect 1.0
import utils 1.0
import shared.stores 1.0
Item {
id: root
// qml Splitter
SplitView {
anchors.fill: parent
ColumnLayout {
SplitView.fillWidth: true
Rectangle {
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: dappsButton.implicitHeight + 20
Layout.preferredHeight: dappsButton.implicitHeight + 20
border.color: "blue"
border.width: 1
ConnectedDappsButton {
id: dappsButton
anchors.centerIn: parent
spacing: 8
onConnectDapp: {
console.warn("TODO: run ConnectDappModal...")
}
}
}
ColumnLayout {}
}
ColumnLayout {
id: optionsSpace
RowLayout {
Text { text: "projectId" }
Text {
id: projectIdText
readonly property string projectId: SystemUtils.getEnvVar("WALLET_CONNECT_PROJECT_ID")
text: projectId.substring(0, 3) + "..." + projectId.substring(projectId.length - 3)
font.bold: true
}
}
// spacer
ColumnLayout {}
}
}
DAppsStore {
wCSDK: WalletConnectSDK {
active: true
projectId: projectIdText.projectId
onSessionRequestEvent: (details) => {
// TODO #14556
console.debug(`@dd onSessionRequestEvent: ${JSON.stringify(details)}`)
}
}
}
}
// category: Popups

View File

@ -0,0 +1,174 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQml 2.15
import Qt.labs.settings 1.0
import QtTest 1.15
import StatusQ.Core 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Popups.Dialog 0.1
import Models 1.0
import Storybook 1.0
import AppLayouts.Wallet.controls 1.0
import AppLayouts.Wallet.services.dapps 1.0
import SortFilterProxyModel 0.2
import AppLayouts.Wallet.panels 1.0
import utils 1.0
import shared.stores 1.0
Item {
id: root
// qml Splitter
SplitView {
anchors.fill: parent
ColumnLayout {
SplitView.fillWidth: true
Rectangle {
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: dappsWorkflow.implicitHeight + 20
Layout.preferredHeight: dappsWorkflow.implicitHeight + 20
border.color: "blue"
border.width: 1
DAppsWorkflow {
id: dappsWorkflow
anchors.centerIn: parent
spacing: 8
}
}
ColumnLayout {}
}
ColumnLayout {
id: optionsSpace
RowLayout {
Text { text: "projectId" }
Text {
id: projectIdText
readonly property string projectId: SystemUtils.getEnvVar("WALLET_CONNECT_PROJECT_ID")
text: projectId.substring(0, 3) + "..." + projectId.substring(projectId.length - 3)
font.bold: true
}
}
// spacer
ColumnLayout {}
RowLayout {
Text { text: "URI" }
TextField {
id: pairUriInput
placeholderText: "Enter WC Pair URI"
text: settings.pairUri
onTextChanged: {
settings.pairUri = text
}
Layout.fillWidth: true
}
}
CheckBox {
id: openPairCheckBox
text: "Open Pair"
checked: settings.openPair
onCheckedChanged: {
settings.openPair = checked
if (checked) {
d.startPairing()
}
}
Connections {
target: dappsWorkflow
// Open Pairing workflow if selected in the side bar
function onDAppsListReady() {
if (!d.startPairingWorkflowActive)
return
let items = InspectionUtils.findVisualsByTypeName(dappsWorkflow, "DAppsListPopup")
if (items.length === 1) {
let buttons = InspectionUtils.findVisualsByTypeName(items[0], "StatusButton")
if (buttons.length === 1) {
buttons[0].clicked()
}
}
}
function onConnectDappReady() {
if (!d.startPairingWorkflowActive)
return
if (pairUriInput.text.length > 0) {
let items = InspectionUtils.findVisualsByTypeName(dappsWorkflow, "StatusBaseInput")
if (items.length === 1) {
items[0].text = pairUriInput.text
}
}
d.startPairingWorkflowActive = false
}
}
}
}
}
DAppsStore {
wCSDK: WalletConnectSDK {
active: true
projectId: projectIdText.projectId
onSessionRequestEvent: (details) => {
// TODO #14556
console.debug(`@dd onSessionRequestEvent: ${JSON.stringify(details)}`)
}
}
}
QtObject {
id: d
property bool startPairingWorkflowActive: false
function startPairing() {
startPairingWorkflowActive = true
if(root.visible) {
dappsWorkflow.clicked()
}
}
}
onVisibleChanged: {
if (visible && d.startPairingWorkflowActive) {
d.startPairing()
}
}
Settings {
id: settings
property bool openPair: false
property string pairUri: ""
}
}
// category: Wallet

View File

@ -16,15 +16,15 @@ Item {
Component {
id: componentUnderTest
ConnectedDappsButton {
DAppsWorkflow {
}
}
TestCase {
name: "ConnectedDappsButton"
name: "DAppsWorkflow"
when: windowShown
property ConnectedDappsButton controlUnderTest: null
property DAppsWorkflow controlUnderTest: null
function init() {
controlUnderTest = createTemporaryObject(componentUnderTest, root)

View File

@ -67,24 +67,36 @@ QtObject {
}
function findItemsByTypeName(root, typeName) {
return findVisualsByTypeName(root, typeName, true)
}
function findVisualsByTypeName(root, typeName, onlyItems = false) {
const items = []
const stack = [root]
while (stack.length) {
const item = stack.pop()
if (!item.visible || item.opacity === 0)
continue
const name = baseName(item)
if (!onlyItems && name === "QQuickLoader") {
if(item.item)
stack.push(item.item)
}
if (!item.visible || item.opacity === 0)
continue
if (name === typeName) {
items.push(item)
continue
}
for (let i = 0; i < item.children.length; i++)
stack.push(item.children[i])
// Popup will have contentChildren instead of children
let children = onlyItems || item.children ? item.children : item.contentChildren
if(children) {
for (let i = 0; i < children.length; i++)
stack.push(children[i])
}
}
return items

View File

@ -1,5 +1,4 @@
import QtQuick 2.15
import QtGraphicalEffects 1.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
@ -11,10 +10,6 @@ import StatusQ.Controls 0.1
StatusButton {
id: root
property int menuWidth: 312
signal connectDapp()
implicitHeight: 38
size: StatusBaseButton.Size.Small
@ -29,70 +24,4 @@ StatusButton {
icon.height: 16
icon.width: 16
icon.color: hovered ? Theme.palette.directColor1 : Theme.palette.baseColor1
highlighted: popup.opened
onClicked: {
if (popup.opened) {
popup.close()
return
}
popup.x = width - root.menuWidth - 2 * popup.padding
popup.y = height + 4
popup.open()
}
Popup {
id: popup
objectName: "dappsPopup"
contentWidth: root.menuWidth
contentHeight: list.height
modal: false
padding: 8
closePolicy: Popup.CloseOnEscape | Popup.CloseOnOutsideClick | Popup.CloseOnPressOutside
background: Rectangle {
id: bckgContent
color: Theme.palette.statusMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
anchors.fill: parent
source: bckgContent
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
}
ColumnLayout {
id: list
anchors.left: parent.left
anchors.right: parent.right
width: parent.width
spacing: 8
ShapeRectangle {
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
text: qsTr("Connected dApps will appear here")
}
StatusButton {
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
text: qsTr("Connect a dApp via WalletConnect")
onClicked: {
root.connectDapp()
popup.close()
}
}
}
}
}

View File

@ -0,0 +1,67 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import AppLayouts.Wallet.controls 1.0
import shared.popups.walletconnect 1.0
ConnectedDappsButton {
id: root
signal dAppsListReady()
signal connectDappReady()
onClicked: {
dappsListLoader.active = true
}
highlighted: dappsListLoader.active
Loader {
id: connectDappLoader
active: false
onLoaded: {
item.open()
root.connectDappReady()
}
sourceComponent: ConnectDappModal {
visible: true
onClosed: connectDappLoader.active = false
onPair: (uri) => {
this.close()
console.debug(`TODO(#14556): ConnectionRequestDappModal with ${uri}`)
}
}
}
Loader {
id: dappsListLoader
active: false
onLoaded: {
item.open()
root.dAppsListReady()
}
sourceComponent: DAppsListPopup {
visible: true
onConnectDapp: {
connectDappLoader.active = true
this.close()
}
onOpened: {
this.x = root.width - this.menuWidth - 2 * this.padding
this.y = root.height + 4
}
onClosed: dappsListLoader.active = false
}
}
}

View File

@ -11,8 +11,6 @@ import StatusQ.Popups 0.1
import SortFilterProxyModel 0.2
import shared.popups.walletconnect 1.0
import utils 1.0
import "../controls"
@ -76,34 +74,12 @@ Item {
Layout.alignment: Qt.AlignTrailing
Layout.topMargin: 5
ConnectedDappsButton {
DAppsWorkflow {
Layout.alignment: Qt.AlignTop
spacing: 8
visible: !root.walletStore.showSavedAddresses && Global.featureFlags.dappsEnabled
onConnectDapp: {
connectDappLoader.active = true
}
Loader {
id: connectDappLoader
active: false
onLoaded: item.open()
sourceComponent: ConnectDappModal {
visible: true
onClosed: connectDappLoader.active = false
onPair: (uri) => {
this.close()
console.debug(`TODO(#14556): ConnectionRequestDappModal with ${uri}`)
}
}
}
}
StatusButton {

View File

@ -5,3 +5,4 @@ ActivityFilterPanel 1.0 ActivityFilterPanel.qml
ManageAssetsPanel 1.0 ManageAssetsPanel.qml
ManageCollectiblesPanel 1.0 ManageCollectiblesPanel.qml
ManageHiddenPanel 1.0 ManageHiddenPanel.qml
DAppsWorkflow 1.0 DAppsWorkflow.qml

View File

@ -0,0 +1,67 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.15
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import shared.controls 1.0
Popup {
id: root
objectName: "dappsPopup"
property int menuWidth: 312
signal connectDapp()
contentWidth: root.menuWidth
contentHeight: list.height
modal: false
padding: 8
closePolicy: Popup.CloseOnEscape | Popup.CloseOnOutsideClick | Popup.CloseOnPressOutside
background: Rectangle {
id: bckgContent
color: Theme.palette.statusMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
anchors.fill: parent
source: bckgContent
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
}
ColumnLayout {
id: list
anchors.left: parent.left
anchors.right: parent.right
width: parent.width
spacing: 8
ShapeRectangle {
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
text: qsTr("Connected dApps will appear here")
}
StatusButton {
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
text: qsTr("Connect a dApp via WalletConnect")
onClicked: {
root.connectDapp()
}
}
}
}

View File

@ -1 +1,2 @@
ConnectDappModal 1.0 ConnectDappModal.qml
ConnectDappModal 1.0 ConnectDappModal.qml
DAppsListPopup 1.0 DAppsListPopup.qml