feat(WC-establish-connection): Fine-tune dApps button
1. Transform the dApps button into a combo box and add badge indicator + tooltip 2. Add storybook page 3. Adding tests 4. Minor fixes - dApps popup width, ModelUtils imports
This commit is contained in:
parent
c59ac4f3f0
commit
4bcda69d4a
|
@ -341,7 +341,7 @@ Item {
|
|||
function startTestCase() {
|
||||
d.activeTestCase = settings.testCase
|
||||
if(root.visible) {
|
||||
dappsWorkflow.clicked()
|
||||
dappsWorkflow.popup.open()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
width: 400
|
||||
height: 400
|
||||
|
||||
Item {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
DappsComboBox {
|
||||
id: connectedDappComboBox
|
||||
anchors.centerIn: parent
|
||||
model: emptyModelCheckbox.checked ? emptyModel : dappsModel
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: emptyModel
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: dappsModel
|
||||
ListElement {
|
||||
name: "Test dApp 1"
|
||||
url: "https://dapp.test/1"
|
||||
iconUrl: "https://se-sdk-dapp.vercel.app/assets/eip155:1.png"
|
||||
}
|
||||
ListElement {
|
||||
name: "Test dApp 2"
|
||||
url: "https://dapp.test/2"
|
||||
iconUrl: "https://react-app.walletconnect.com/assets/eip155-1.png"
|
||||
}
|
||||
ListElement {
|
||||
name: "Test dApp 3"
|
||||
url: "https://dapp.test/3"
|
||||
iconUrl: "https://react-app.walletconnect.com/assets/eip155-1.png"
|
||||
}
|
||||
ListElement {
|
||||
name: "Test dApp 4 - very long name !!!!!!!!!!!!!!!!"
|
||||
url: "https://dapp.test/4"
|
||||
iconUrl: "https://react-app.walletconnect.com/assets/eip155-1.png"
|
||||
}
|
||||
ListElement {
|
||||
name: "Test dApp 5 - very long url"
|
||||
url: "https://dapp.test/very_long/url/unusual"
|
||||
iconUrl: "https://react-app.walletconnect.com/assets/eip155-1.png"
|
||||
}
|
||||
ListElement {
|
||||
name: "Test dApp 6"
|
||||
url: "https://dapp.test/6"
|
||||
iconUrl: "https://react-app.walletconnect.com/assets/eip155-1.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Pane {
|
||||
id: controls
|
||||
SplitView.preferredWidth: 300
|
||||
SplitView.fillHeight: true
|
||||
|
||||
ColumnLayout {
|
||||
CheckBox {
|
||||
id: emptyModelCheckbox
|
||||
text: "Empty model"
|
||||
checked: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// category: Controls
|
||||
|
||||
// https://www.figma.com/design/HrmZp1y4S77QJezRFRl6ku/dApp-Interactions---Milestone-1?node-id=130-31949&t=hnzB58fTnEnx2z84-0
|
|
@ -14,6 +14,8 @@ public slots:
|
|||
QGuiApplication::setOrganizationName(QStringLiteral("Status"));
|
||||
QGuiApplication::setOrganizationDomain(QStringLiteral("status.im"));
|
||||
|
||||
qputenv("QT_QUICK_CONTROLS_HOVER_ENABLED", QByteArrayLiteral("1"));
|
||||
|
||||
const QStringList additionalImportPaths {
|
||||
STATUSQ_MODULE_IMPORT_PATH,
|
||||
QML_IMPORT_ROOT + QStringLiteral("/../ui/app"),
|
||||
|
|
|
@ -537,7 +537,7 @@ Item {
|
|||
// waitForRendering(controlUnderTest)
|
||||
// compare(dappsListReadySpy.count, 1, "expected dappsListReady signal to be emitted")
|
||||
|
||||
// let popup = findChild(controlUnderTest, "dappsPopup")
|
||||
// let popup = findChild(controlUnderTest, "dappsListPopup")
|
||||
// verify(!!popup)
|
||||
// verify(popup.opened)
|
||||
|
||||
|
@ -553,7 +553,7 @@ Item {
|
|||
// mouseClick(controlUnderTest)
|
||||
// waitForRendering(controlUnderTest)
|
||||
|
||||
// let popup = findChild(controlUnderTest, "dappsPopup")
|
||||
// let popup = findChild(controlUnderTest, "dappsListPopup")
|
||||
// verify(!!popup)
|
||||
// verify(popup.opened)
|
||||
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
import QtQuick 2.15
|
||||
import QtQml.Models 2.15
|
||||
|
||||
import QtTest 1.15
|
||||
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: 600
|
||||
height: 400
|
||||
|
||||
Component {
|
||||
id: componentUnderTest
|
||||
DappsComboBox {
|
||||
anchors.centerIn: parent
|
||||
model: ListModel {}
|
||||
}
|
||||
}
|
||||
|
||||
SignalSpy {
|
||||
id: dappsListReadySpy
|
||||
target: controlUnderTest
|
||||
signalName: "dappsListReady"
|
||||
}
|
||||
|
||||
property DappsComboBox controlUnderTest: null
|
||||
|
||||
TestCase {
|
||||
name: "DappsComboBox"
|
||||
when: windowShown
|
||||
|
||||
function init() {
|
||||
controlUnderTest = createTemporaryObject(componentUnderTest, root)
|
||||
dappsListReadySpy.clear()
|
||||
}
|
||||
|
||||
function test_basicGeometry() {
|
||||
verify(controlUnderTest.width > 0)
|
||||
verify(controlUnderTest.height > 0)
|
||||
}
|
||||
|
||||
function test_showStatusIndicator() {
|
||||
const indicator = findChild(controlUnderTest, "dappBadge")
|
||||
compare(indicator.visible, false)
|
||||
|
||||
controlUnderTest.model.append({name: "Test dApp 1", url: "https://dapp.test/1", iconUrl: "https://se-sdk-dapp.vercel.app/assets/eip155:1.png"})
|
||||
compare(indicator.visible, true)
|
||||
|
||||
controlUnderTest.model.clear()
|
||||
compare(indicator.visible, false)
|
||||
}
|
||||
|
||||
function test_dappIcon() {
|
||||
const icon = findChild(controlUnderTest, "dappIcon")
|
||||
compare(icon.icon, "dapp")
|
||||
compare(icon.width, 16)
|
||||
compare(icon.height, 16)
|
||||
compare(icon.status, Image.Ready)
|
||||
}
|
||||
|
||||
function test_openingPopup() {
|
||||
mouseClick(controlUnderTest)
|
||||
const popup = findChild(controlUnderTest, "dappsListPopup")
|
||||
compare(popup.visible, true)
|
||||
compare(popup.x, controlUnderTest.width - popup.width)
|
||||
compare(popup.y, controlUnderTest.height + 4)
|
||||
compare(popup.width, 312)
|
||||
verify(popup.height > 0)
|
||||
compare(dappsListReadySpy.count, 1)
|
||||
|
||||
const background = findChild(controlUnderTest, "dappsBackground")
|
||||
compare(background.active, true)
|
||||
|
||||
mouseClick(controlUnderTest)
|
||||
compare(popup.visible, false)
|
||||
compare(background.active, false)
|
||||
}
|
||||
|
||||
function test_hoverState() {
|
||||
const background = findChild(controlUnderTest, "dappsBackground")
|
||||
compare(background.active, false)
|
||||
|
||||
mouseMove(controlUnderTest, controlUnderTest.width/2, controlUnderTest.height/2)
|
||||
compare(background.active, true)
|
||||
compare(controlUnderTest.hovered, true)
|
||||
const dappTooltip = findChild(controlUnderTest, "dappTooltip")
|
||||
wait(dappTooltip.delay + 50)
|
||||
compare(dappTooltip.visible, true)
|
||||
compare(dappTooltip.text, "dApp connections")
|
||||
verify(dappTooltip.width > 0)
|
||||
verify(dappTooltip.height > 0)
|
||||
verify(dappTooltip.y > controlUnderTest.height)
|
||||
|
||||
mouseMove(root)
|
||||
compare(background.active, false)
|
||||
compare(dappTooltip.visible, false)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ pragma Singleton
|
|||
|
||||
import QtQuick 2.14
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Internal 0.1 as Internal
|
||||
|
||||
QtObject {
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import shared.controls 1.0
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
StatusButton {
|
||||
id: root
|
||||
|
||||
implicitHeight: 38
|
||||
|
||||
size: StatusBaseButton.Size.Small
|
||||
|
||||
borderColor: Theme.palette.directColor7
|
||||
normalColor: Theme.palette.transparent
|
||||
hoverColor: Theme.palette.baseColor2
|
||||
textPosition: StatusBaseButton.TextPosition.Left
|
||||
textColor: Theme.palette.baseColor1
|
||||
|
||||
icon.name: "dapp"
|
||||
icon.height: 16
|
||||
icon.width: 16
|
||||
icon.color: hovered ? Theme.palette.directColor1 : Theme.palette.baseColor1
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
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
|
||||
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitHeight: 50
|
||||
|
||||
required property string name
|
||||
required property string url
|
||||
required property string iconUrl
|
||||
|
||||
signal disconnectDapp()
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 8
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 32
|
||||
Layout.preferredHeight: 32
|
||||
|
||||
StatusImage {
|
||||
id: iconImage
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
source: iconUrl
|
||||
visible: !fallbackImage.visible
|
||||
}
|
||||
|
||||
StatusIcon {
|
||||
id: fallbackImage
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
icon: "dapp"
|
||||
color: Theme.palette.baseColor1
|
||||
|
||||
visible: iconImage.isLoading || iconImage.isError || !iconUrl
|
||||
}
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Rectangle {
|
||||
width: iconImage.width
|
||||
height: iconImage.height
|
||||
radius: width / 2
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.leftMargin: 12
|
||||
Layout.rightMargin: 12
|
||||
|
||||
StatusBaseText {
|
||||
text: name
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
font.pixelSize: 13
|
||||
font.bold: true
|
||||
|
||||
elide: Text.ElideRight
|
||||
|
||||
clip: true
|
||||
}
|
||||
StatusBaseText {
|
||||
text: url
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
font.pixelSize: 12
|
||||
color: Theme.palette.baseColor1
|
||||
|
||||
elide: Text.ElideRight
|
||||
|
||||
clip: true
|
||||
}
|
||||
}
|
||||
|
||||
// TODO #14588 - Show tooltip on hover "Disconnect dApp"
|
||||
StatusRoundButton {
|
||||
implicitWidth: 32
|
||||
implicitHeight: 32
|
||||
radius: width / 2
|
||||
|
||||
icon.name: "disconnect"
|
||||
|
||||
onClicked: {
|
||||
console.debug(`TODO #14755 - Disconnect ${name}`)
|
||||
//root.disconnectDapp()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtGraphicalEffects 1.15
|
||||
|
||||
import shared.controls 1.0
|
||||
import shared.popups.walletconnect 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Components.private 0.1 as SQP
|
||||
|
||||
|
||||
ComboBox {
|
||||
id: root
|
||||
|
||||
signal dappsListReady
|
||||
signal pairDapp
|
||||
|
||||
implicitHeight: 38
|
||||
implicitWidth: 38
|
||||
|
||||
background: SQP.StatusComboboxBackground {
|
||||
objectName: "dappsBackground"
|
||||
active: root.down || root.hovered
|
||||
}
|
||||
|
||||
indicator: null
|
||||
|
||||
contentItem: Item {
|
||||
objectName: "dappsContentItem"
|
||||
StatusBadge {
|
||||
objectName: "dappBadge"
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.margins: 5
|
||||
width: 6
|
||||
height: 6
|
||||
visible: root.delegateModel.count > 0
|
||||
}
|
||||
|
||||
StatusIcon {
|
||||
objectName: "dappIcon"
|
||||
anchors.centerIn: parent
|
||||
width: 16
|
||||
height: 16
|
||||
icon: "dapp"
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
|
||||
delegate: DAppDelegate {
|
||||
width: ListView.view.width
|
||||
}
|
||||
|
||||
popup: DAppsListPopup {
|
||||
objectName: "dappsListPopup"
|
||||
|
||||
x: root.width - width
|
||||
y: root.height + 4
|
||||
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||
|
||||
delegateModel: root.delegateModel
|
||||
|
||||
onPairWCDapp: {
|
||||
root.pairDapp()
|
||||
this.close()
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
root.dappsListReady()
|
||||
}
|
||||
}
|
||||
|
||||
StatusToolTip {
|
||||
id: tooltip
|
||||
objectName: "dappTooltip"
|
||||
visible: root.hovered && !root.down
|
||||
text: qsTr("dApp connections")
|
||||
orientation: StatusToolTip.Orientation.Bottom
|
||||
y: root.height + 14
|
||||
}
|
||||
}
|
|
@ -14,8 +14,8 @@ MaxSendButton 1.0 MaxSendButton.qml
|
|||
InformationTileAssetDetails 1.0 InformationTileAssetDetails.qml
|
||||
StatusNetworkListItemTag 1.0 StatusNetworkListItemTag.qml
|
||||
CollectibleBalanceTag 1.0 CollectibleBalanceTag.qml
|
||||
ConnectedDappsButton 1.0 ConnectedDappsButton.qml
|
||||
CollectibleLinksTags 1.0 CollectibleLinksTags.qml
|
||||
DappsComboBox 1.0 DappsComboBox.qml
|
||||
SwapExchangeButton 1.0 SwapExchangeButton.qml
|
||||
EditSlippagePanel 1.0 EditSlippagePanel.qml
|
||||
TokenSelector 1.0 TokenSelector.qml
|
||||
|
|
|
@ -11,19 +11,18 @@ import AppLayouts.Wallet.services.dapps.types 1.0
|
|||
import shared.stores 1.0
|
||||
import utils 1.0
|
||||
|
||||
ConnectedDappsButton {
|
||||
DappsComboBox {
|
||||
id: root
|
||||
|
||||
required property WalletConnectService wcService
|
||||
|
||||
signal dappsListReady()
|
||||
signal pairWCReady()
|
||||
|
||||
onClicked: {
|
||||
dappsListLoader.active = true
|
||||
}
|
||||
model: root.wcService.dappsModel
|
||||
|
||||
highlighted: dappsListLoader.active
|
||||
onPairDapp: {
|
||||
pairWCLoader.active = true
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: pairWCLoader
|
||||
|
@ -47,34 +46,6 @@ ConnectedDappsButton {
|
|||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: dappsListLoader
|
||||
|
||||
active: false
|
||||
|
||||
onLoaded: {
|
||||
item.open()
|
||||
root.dappsListReady()
|
||||
}
|
||||
|
||||
sourceComponent: DAppsListPopup {
|
||||
visible: true
|
||||
|
||||
model: root.wcService.dappsModel
|
||||
|
||||
onPairWCDapp: {
|
||||
pairWCLoader.active = true
|
||||
this.close()
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
this.x = root.width - this.contentWidth - 2 * this.padding
|
||||
this.y = root.height + 4
|
||||
}
|
||||
onClosed: dappsListLoader.active = false
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: connectDappLoader
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQml.Models 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtGraphicalEffects 1.15
|
||||
|
||||
|
@ -15,10 +16,12 @@ Popup {
|
|||
|
||||
objectName: "dappsPopup"
|
||||
|
||||
required property var model
|
||||
required property DelegateModel delegateModel
|
||||
|
||||
signal pairWCDapp()
|
||||
|
||||
width: 312
|
||||
|
||||
modal: false
|
||||
padding: 8
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnOutsideClick | Popup.CloseOnPressOutside
|
||||
|
@ -41,11 +44,9 @@ Popup {
|
|||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
contentItem: ColumnLayout {
|
||||
id: mainLayout
|
||||
|
||||
implicitWidth: 280
|
||||
|
||||
spacing: 8
|
||||
|
||||
ShapeRectangle {
|
||||
|
@ -84,13 +85,9 @@ Popup {
|
|||
Layout.preferredHeight: contentHeight
|
||||
Layout.maximumHeight: 280
|
||||
|
||||
model: root.model
|
||||
model: root.delegateModel
|
||||
visible: !listPlaceholder.visible
|
||||
|
||||
delegate: DAppDelegate {
|
||||
implicitWidth: listView.width
|
||||
}
|
||||
|
||||
ScrollBar.vertical: null
|
||||
}
|
||||
|
||||
|
@ -105,96 +102,4 @@ Popup {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
component DAppDelegate: Item {
|
||||
implicitHeight: 50
|
||||
|
||||
required property string name
|
||||
required property string url
|
||||
required property string iconUrl
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 8
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 32
|
||||
Layout.preferredHeight: 32
|
||||
|
||||
StatusImage {
|
||||
id: iconImage
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
source: iconUrl
|
||||
visible: !fallbackImage.visible
|
||||
}
|
||||
|
||||
StatusIcon {
|
||||
id: fallbackImage
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
icon: "dapp"
|
||||
color: Theme.palette.baseColor1
|
||||
|
||||
visible: iconImage.isLoading || iconImage.isError || !iconUrl
|
||||
}
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Rectangle {
|
||||
width: iconImage.width
|
||||
height: iconImage.height
|
||||
radius: width / 2
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.leftMargin: 12
|
||||
Layout.rightMargin: 12
|
||||
|
||||
StatusBaseText {
|
||||
text: name
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
font.pixelSize: 13
|
||||
font.bold: true
|
||||
|
||||
elide: Text.ElideRight
|
||||
|
||||
clip: true
|
||||
}
|
||||
StatusBaseText {
|
||||
text: url
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
font.pixelSize: 12
|
||||
color: Theme.palette.baseColor1
|
||||
|
||||
elide: Text.ElideRight
|
||||
|
||||
clip: true
|
||||
}
|
||||
}
|
||||
|
||||
// TODO #14588 - Show tooltip on hover "Disconnect dApp"
|
||||
StatusRoundButton {
|
||||
implicitWidth: 32
|
||||
implicitHeight: 32
|
||||
radius: width / 2
|
||||
|
||||
icon.name: "disconnect"
|
||||
|
||||
onClicked: {
|
||||
console.debug(`TODO #14755 - Disconnect ${name}`)
|
||||
//root.disconnectDapp()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue