feat(@desktop/wallet): fixing some issues in UI alignments

This commit is contained in:
Khushboo Mehta 2024-12-09 13:57:00 +01:00
parent 16e67a2137
commit b6919a3bf5
12 changed files with 165 additions and 125 deletions

View File

@ -22,8 +22,9 @@ SplitView {
width: 595 width: 595
loading: loadingCheckbox.checked loading: loadingCheckbox.checked
error: errorCheckbox.checked
onReviewSendClicked: console.log("review send clicked") onReviewSendClicked: logs.logEvent("review send clicked")
} }
} }
@ -41,11 +42,16 @@ SplitView {
text: "loading" text: "loading"
} }
CheckBox {
id: errorCheckbox
text: "error"
}
Button { Button {
text: "set fees values" text: "set fees values"
onClicked: { onClicked: {
loadingCheckbox.checked = false loadingCheckbox.checked = false
footer.estimateTime = "~60s" footer.estimatedTime = "~60s"
footer.estimatedFees = "1.45 EUR" footer.estimatedFees = "1.45 EUR"
} }
} }

View File

@ -121,10 +121,16 @@ SplitView {
} }
}) })
onFetchFees: { onFormChanged: {
console.log("Fetch fees...") estimatedCryptoFees = ""
d.setFees() estimatedFiatFees = ""
estimatedTime = ""
if(formCorrectlyFilled) {
console.log("Fetch fees...")
d.setFees()
}
} }
onReviewSendClicked: console.log("Review send clicked") onReviewSendClicked: console.log("Review send clicked")
Binding on selectedAccountAddress { Binding on selectedAccountAddress {
@ -488,7 +494,7 @@ SplitView {
} }
} }
LogsAndControlsPanel { Pane {
SplitView.minimumHeight: 100 SplitView.minimumHeight: 100
SplitView.minimumWidth: 300 SplitView.minimumWidth: 300
SplitView.maximumWidth: 380 SplitView.maximumWidth: 380

View File

@ -1,5 +1,6 @@
import QtQuick 2.14 import QtQuick 2.14
import QtQuick.Controls 2.14 import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
@ -9,7 +10,6 @@ import AppLayouts.Wallet.panels 1.0
SplitView { SplitView {
orientation: Qt.Vertical orientation: Qt.Vertical
Logs { id: logs }
Rectangle { Rectangle {
SplitView.fillHeight: true SplitView.fillHeight: true
@ -23,20 +23,26 @@ SplitView {
cryptoFees: qsTr("0.0007 ETH") cryptoFees: qsTr("0.0007 ETH")
fiatFees: qsTr("1.45 EUR") fiatFees: qsTr("1.45 EUR")
loading: loadingCheckbox.checked loading: loadingCheckbox.checked
error: errorCheckbox.checked
} }
} }
LogsAndControlsPanel { Pane {
id: logsAndControlsPanel id: logsAndControlsPanel
SplitView.minimumHeight: 100 SplitView.minimumHeight: 100
SplitView.preferredHeight: 200 SplitView.preferredHeight: 200
logsView.logText: logs.logText ColumnLayout {
CheckBox {
id: loadingCheckbox
text: "loading"
}
CheckBox { CheckBox {
id: loadingCheckbox id: errorCheckbox
text: "loading" text: "error"
}
} }
} }
} }

View File

@ -11,7 +11,7 @@ Rectangle {
border.width: 1 border.width: 1
border.color: Theme.palette.directColor7 border.color: Theme.palette.directColor7
radius: 8 radius: 8
color: root.active ? Theme.palette.baseColor2 : "transparent" color: root.active ? Theme.palette.directColor8 : "transparent"
HoverHandler { HoverHandler {
cursorShape: root.enabled ? Qt.PointingHandCursor : undefined cursorShape: root.enabled ? Qt.PointingHandCursor : undefined
} }

View File

@ -17,9 +17,6 @@ Control {
/** Expected model structure: see SearchableCollectiblesPanel::model **/ /** Expected model structure: see SearchableCollectiblesPanel::model **/
property alias collectiblesModel: tokenSelectorPanel.collectiblesModel property alias collectiblesModel: tokenSelectorPanel.collectiblesModel
/** Exposes insatnce of popup **/
property var popup: dropdown
/** Sets size of the TokenSelectorButton **/ /** Sets size of the TokenSelectorButton **/
property alias size: tokenSelectorButton.size property alias size: tokenSelectorButton.size
@ -45,6 +42,10 @@ Control {
} }
} }
function close() {
dropdown.close()
}
QObject { QObject {
id: d id: d

View File

@ -65,7 +65,7 @@ RowLayout {
/** signal to propagate that a collectible was selected **/ /** signal to propagate that a collectible was selected **/
signal collectibleSelected(string key) signal collectibleSelected(string key)
/** signal to propagate that a network was selected **/ /** signal to propagate that a network was selected **/
signal networkSelected(string chainId) signal networkSelected(int chainId)
/** input function for programatic selection of token /** input function for programatic selection of token
(asset/collectible/collection) **/ (asset/collectible/collection) **/
@ -79,7 +79,7 @@ RowLayout {
// if not closed during scrolling they move with the header and it feels undesirable // if not closed during scrolling they move with the header and it feels undesirable
onIsScrollingChanged: { onIsScrollingChanged: {
tokenSelector.popup.close() tokenSelector.close()
networkFilter.control.popup.close() networkFilter.control.popup.close()
} }
@ -135,7 +135,7 @@ RowLayout {
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
control.bottomPadding: 0 control.popup.y: networkFilter.height
flatNetworks: root.networksModel flatNetworks: root.networksModel

View File

@ -1,6 +1,6 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.14 import QtQuick.Layouts 1.15
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
@ -16,22 +16,23 @@ Control {
property string fiatFees property string fiatFees
/** property to set loading state in the fees component **/ /** property to set loading state in the fees component **/
property bool loading property bool loading
/** property to set error state in the fees component **/
property bool error
QtObject { QtObject {
id: d id: d
readonly property string loadingText: "----------" readonly property string loadingText: "XXXXXXXXXX"
} }
implicitHeight: 64 implicitHeight: 64
padding: Theme.padding padding: Theme.padding
topPadding: 12 verticalPadding: 12
bottomPadding: 12
background: Rectangle { background: Rectangle {
color: Theme.palette.indirectColor1 color: Theme.palette.indirectColor1
radius: 8 radius: Theme.radius
} }
contentItem: RowLayout { contentItem: RowLayout {
@ -64,7 +65,8 @@ Control {
Layout.fillWidth: true Layout.fillWidth: true
loading: root.loading loading: root.loading
customColor: Theme.palette.baseColor1 customColor: root.error ? Theme.palette.dangerColor1:
Theme.palette.baseColor1
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
lineHeight: 22 lineHeight: 22
@ -78,7 +80,8 @@ Control {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
loading: root.loading loading: root.loading
customColor: Theme.palette.baseColor1 customColor: root.error ? Theme.palette.dangerColor1:
Theme.palette.baseColor1
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
lineHeight: 22 lineHeight: 22

View File

@ -1,10 +1,11 @@
import QtQuick 2.14 import QtQuick 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15 import QtGraphicalEffects 1.15
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Popups.Dialog 0.1 import StatusQ.Popups.Dialog 0.1
Rectangle { Control {
id: root id: root
/** /**
@ -48,10 +49,10 @@ Rectangle {
Not using visible property directly here as the animation on Not using visible property directly here as the animation on
implicitHeight doesnt work implicitHeight doesnt work
**/ **/
property bool isScrolling property bool stickyHeaderVisible
/** input property for programatic selection of network **/ /** input property for programatic selection of network **/
property int selectedChainId: -1 property int selectedChainId
/** signal to propagate that an asset was selected **/ /** signal to propagate that an asset was selected **/
signal assetSelected(string key) signal assetSelected(string key)
@ -60,7 +61,7 @@ Rectangle {
/** signal to propagate that a collectible was selected **/ /** signal to propagate that a collectible was selected **/
signal collectibleSelected(string key) signal collectibleSelected(string key)
/** signal to propagate that a network was selected **/ /** signal to propagate that a network was selected **/
signal networkSelected(string chainId) signal networkSelected(int chainId)
/** input function for programatic selection of token /** input function for programatic selection of token
(asset/collectible/collection) **/ (asset/collectible/collection) **/
@ -68,48 +69,56 @@ Rectangle {
sendModalHeader.setToken(name, icon, key) sendModalHeader.setToken(name, icon, key)
} }
enabled: root.isScrolling QtObject {
color: Theme.palette.baseColor3 id: d
radius: 8 readonly property int bottomMargin: 12
}
implicitHeight: root.isScrolling ? implicitHeight: root.stickyHeaderVisible ?
sendModalHeader.implicitHeight + implicitContentHeight + Theme.padding + d.bottomMargin : 0
sendModalHeader.anchors.topMargin +
sendModalHeader.anchors.bottomMargin:
0
implicitWidth: sendModalHeader.implicitWidth +
sendModalHeader.anchors.leftMargin +
sendModalHeader.anchors.rightMargin
horizontalPadding: Theme.xlPadding
bottomPadding: d.bottomMargin
topPadding: root.stickyHeaderVisible ? Theme.padding : -implicitContentHeight - Theme.padding
// Drawer animation for stickey heade
Behavior on implicitHeight { Behavior on implicitHeight {
NumberAnimation { duration: 350 } NumberAnimation { duration: 350 }
} }
Behavior on topPadding {
// cover for the bottom rounded corners NumberAnimation { duration: 350 }
Rectangle {
width: parent.width
height: parent.radius
anchors.bottom: parent.bottom
color: parent.color
} }
SendModalHeader { background: Rectangle {
id: sendModalHeader color: root.implicitHeight > d.bottomMargin ? Theme.palette.baseColor3: Theme.palette.transparent
radius: 8
width: parent.width layer.enabled: true
layer.effect: DropShadow {
anchors { horizontalOffset: 0
fill: parent verticalOffset: 2
leftMargin: Theme.xlPadding samples: 37
rightMargin: Theme.xlPadding color: Theme.palette.dropShadow
topMargin: 16
bottomMargin: 12
} }
// cover for the bottom rounded corners
Rectangle {
width: parent.width
height: parent.radius
anchors.bottom: parent.bottom
color: parent.color
}
StatusDialogDivider {
anchors.bottom: parent.bottom
width: parent.width
}
}
contentItem: SendModalHeader {
id: sendModalHeader
isStickyHeader: true isStickyHeader: true
isScrolling: root.isScrolling isScrolling: root.stickyHeaderVisible
networksModel: root.networksModel networksModel: root.networksModel
assetsModel: root.assetsModel assetsModel: root.assetsModel
@ -122,18 +131,4 @@ Rectangle {
onAssetSelected: root.assetSelected(key) onAssetSelected: root.assetSelected(key)
onNetworkSelected: root.networkSelected(chainId) onNetworkSelected: root.networkSelected(chainId)
} }
StatusDialogDivider {
anchors.bottom: parent.bottom
width: parent.width
}
layer.enabled: true
layer.effect: DropShadow {
horizontalOffset: 0
verticalOffset: 2
samples: 37
color: Theme.palette.dropShadow
}
} }

View File

@ -1,5 +1,5 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Layouts 1.14 import QtQuick.Layouts 1.15
import StatusQ 0.1 import StatusQ 0.1
import StatusQ.Core 0.1 import StatusQ.Core 0.1
@ -102,6 +102,9 @@ StatusDialog {
e.g. 1000000000000000000 for 1 ETH **/ e.g. 1000000000000000000 for 1 ETH **/
readonly property string selectedAmountInBaseUnit: amountToSend.amount readonly property string selectedAmountInBaseUnit: amountToSend.amount
/** property to scheck if form has been filled correctly **/
readonly property bool formCorrectlyFilled: d.allValuesFilledCorrectly()
/** TODO: replace with new and improved recipient selector StatusDateRangePicker /** TODO: replace with new and improved recipient selector StatusDateRangePicker
TBD under https://github.com/status-im/status-desktop/issues/16916 **/ TBD under https://github.com/status-im/status-desktop/issues/16916 **/
property alias selectedRecipientAddress: recipientsPanel.selectedRecipientAddress property alias selectedRecipientAddress: recipientsPanel.selectedRecipientAddress
@ -114,14 +117,22 @@ StatusDialog {
/** Output signal to request signing of the transaction **/ /** Output signal to request signing of the transaction **/
signal reviewSendClicked() signal reviewSendClicked()
/** Output signal to request fetching fees **/ /** Output signal to inform that the forms been updated **/
signal fetchFees() signal formChanged()
QtObject { QtObject {
id: d id: d
readonly property bool isScrolling: readonly property real scrollViewContentY: scrollView.flickable.contentY
scrollView.flickable.contentY > sendModalHeader.height onScrollViewContentYChanged: {
const buffer = sendModalHeader.height + scrollViewLayout.spacing
if (scrollViewContentY > buffer) {
d.stickyHeaderVisible = true
} else if (scrollViewContentY === 0) {
d.stickyHeaderVisible = false
}
}
property bool stickyHeaderVisible: false
// Used to get asset entry if selected token is an asset // Used to get asset entry if selected token is an asset
readonly property var selectedAssetEntry: ModelEntry { readonly property var selectedAssetEntry: ModelEntry {
@ -215,20 +226,7 @@ StatusDialog {
root.selectedAmount, root.selectedAmount,
amountToSend.markAsInvalid, amountToSend.markAsInvalid,
amountToSend.valid] amountToSend.valid]
onCombinedPropertyChangedHandlerChanged: Qt.callLater(() => d.fetchFees()) onCombinedPropertyChangedHandlerChanged: Qt.callLater(() => root.formChanged())
function resetFees() {
root.estimatedCryptoFees = ""
root.estimatedFiatFees = ""
root.estimatedTime = ""
}
function fetchFees() {
resetFees()
if(allValuesFilledCorrectly()) {
root.fetchFees()
}
}
readonly property bool feesIsLoading: !root.estimatedCryptoFees && readonly property bool feesIsLoading: !root.estimatedCryptoFees &&
!root.estimatedFiatFees && !root.estimatedFiatFees &&
@ -237,8 +235,7 @@ StatusDialog {
width: 556 width: 556
padding: 0 padding: 0
leftPadding: Theme.xlPadding horizontalPadding: Theme.xlPadding
rightPadding: Theme.xlPadding
topMargin: margins + accountSelector.height + Theme.padding topMargin: margins + accountSelector.height + Theme.padding
background: StatusDialogBackground { background: StatusDialogBackground {
@ -287,28 +284,36 @@ StatusDialog {
} }
// Sticky header only visible when scrolling // Sticky header only visible when scrolling
StickySendModalHeader { Item {
id: stickySendModalHeader height: childrenRect.height + Theme.smallPadding
width: root.width
anchors.top: accountSelector.bottom anchors.top: accountSelector.bottom
anchors.topMargin:Theme.padding anchors.topMargin: Theme.padding
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: -Theme.xlPadding anchors.leftMargin: -Theme.xlPadding
anchors.right: parent.right
anchors.rightMargin: -Theme.xlPadding
clip: true
z: 1 z: 1
isScrolling: d.isScrolling StickySendModalHeader {
id: stickySendModalHeader
networksModel: root.networksModel width: parent.width
assetsModel: root.assetsModel
collectiblesModel: root.collectiblesModel
selectedChainId: root.selectedChainId stickyHeaderVisible: d.stickyHeaderVisible
onCollectibleSelected: root.selectedTokenKey = key networksModel: root.networksModel
onCollectionSelected: root.selectedTokenKey = key assetsModel: root.assetsModel
onAssetSelected: root.selectedTokenKey = key collectiblesModel: root.collectiblesModel
onNetworkSelected: root.selectedChainId = chainId
selectedChainId: root.selectedChainId
onCollectibleSelected: root.selectedTokenKey = key
onCollectionSelected: root.selectedTokenKey = key
onAssetSelected: root.selectedTokenKey = key
onNetworkSelected: root.selectedChainId = chainId
}
} }
// Main scrollable Layout // Main scrollable Layout
@ -340,7 +345,7 @@ StatusDialog {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 28 Layout.topMargin: 28
isScrolling: d.isScrolling isScrolling: d.stickyHeaderVisible
networksModel: root.networksModel networksModel: root.networksModel
assetsModel: root.assetsModel assetsModel: root.assetsModel
@ -400,8 +405,7 @@ StatusDialog {
return root.fnFormatCurrencyAmount( return root.fnFormatCurrencyAmount(
maxSafeValue, maxSafeValue,
amountToSend.selectedSymbol, amountToSend.selectedSymbol,
{ noSymbol: !amountToSend.fiatMode, { roundingMode: LocaleUtils.RoundingMode.Down
roundingMode: LocaleUtils.RoundingMode.Down
}) })
} }
markAsInvalid: amountToSend.markAsInvalid markAsInvalid: amountToSend.markAsInvalid
@ -474,7 +478,7 @@ StatusDialog {
footer: SendModalFooter { footer: SendModalFooter {
width: root.width width: root.width
estimateTime: root.estimatedTime estimatedTime: root.estimatedTime
estimatedFees: root.estimatedFiatFees estimatedFees: root.estimatedFiatFees
loading: d.feesIsLoading && d.allValuesFilledCorrectly() loading: d.feesIsLoading && d.allValuesFilledCorrectly()

View File

@ -13,9 +13,11 @@ StatusDialogFooter {
/** property to set loading state **/ /** property to set loading state **/
property bool loading property bool loading
/** property to set estimated time **/ /** property to set estimated time **/
property string estimateTime property string estimatedTime
/** property to set estimates fees in fiat **/ /** property to set estimates fees in fiat **/
property string estimatedFees property string estimatedFees
/** property to set error state **/
property bool error
// Signal to propogate Send clicked // Signal to propogate Send clicked
signal reviewSendClicked() signal reviewSendClicked()
@ -29,7 +31,7 @@ StatusDialogFooter {
id: d id: d
readonly property string emptyText: "--" readonly property string emptyText: "--"
readonly property string loadingText: "----------" readonly property string loadingText: "XXXXXXXXXX"
} }
leftButtons: ObjectModel { leftButtons: ObjectModel {
@ -40,17 +42,19 @@ StatusDialogFooter {
spacing: 0 spacing: 0
StatusBaseText { StatusBaseText {
font.weight: Font.Medium
color: Theme.palette.directColor5 color: Theme.palette.directColor5
text: qsTr("Est time") text: qsTr("Est time")
} }
StatusTextWithLoadingState { StatusTextWithLoadingState {
id: estimatedTime id: estimatedTime
customColor: !!root.estimateTime ? Theme.palette.directColor1: font.weight: Font.Medium
customColor: !!root.estimatedTime ? Theme.palette.directColor1:
Theme.palette.directColor5 Theme.palette.directColor5
loading: root.loading loading: root.loading
text: !!root.estimateTime ? root.estimateTime: text: !!root.estimatedTime ? root.estimatedTime:
root.loading ? d.loadingText : d.emptyText root.loading ? d.loadingText : d.emptyText
} }
} }
@ -60,14 +64,18 @@ StatusDialogFooter {
spacing: 0 spacing: 0
StatusBaseText { StatusBaseText {
font.weight: Font.Medium
color: Theme.palette.directColor5 color: Theme.palette.directColor5
text: qsTr("Est fees") text: qsTr("Est fees")
} }
StatusTextWithLoadingState { StatusTextWithLoadingState {
id: estimatedFees id: estimatedFees
customColor: !!root.estimatedFees ? Theme.palette.directColor1: font.weight: Font.Medium
Theme.palette.directColor5 customColor: root.error ? Theme.palette.dangerColor1:
!!root.estimatedFees ?
Theme.palette.directColor1:
Theme.palette.directColor5
loading: root.loading loading: root.loading
text: !!root.estimatedFees ? root.estimatedFees: text: !!root.estimatedFees ? root.estimatedFees:
@ -83,7 +91,7 @@ StatusDialogFooter {
Layout.rightMargin: Theme.padding Layout.rightMargin: Theme.padding
disabledColor: Theme.palette.directColor8 disabledColor: Theme.palette.directColor8
enabled: !!root.estimateTime && enabled: !!root.estimatedTime &&
!!root.estimatedFees && !!root.estimatedFees &&
!root.loading !root.loading

View File

@ -82,10 +82,10 @@ QtObject {
**/ **/
required property var flatNetworksModel required property var flatNetworksModel
/** true if testnet mode is on **/ /** true if testnet mode is on **/
required property var areTestNetworksEnabled required property bool areTestNetworksEnabled
/** whether community tokens are shown in send modal /** whether community tokens are shown in send modal
based on a global setting **/ based on a global setting **/
required property var showCommunityAssetsInSend required property bool showCommunityAssetsInSend
/** required function to format currency amount to locale string **/ /** required function to format currency amount to locale string **/
required property var fnFormatCurrencyAmount required property var fnFormatCurrencyAmount
@ -238,6 +238,15 @@ QtObject {
onClosed: destroy() onClosed: destroy()
onFormChanged: {
estimatedCryptoFees = ""
estimatedFiatFees = ""
estimatedTime = ""
if(formCorrectlyFilled) {
// TODO: call stores fetchSuggestedRoutes api
}
}
TokenSelectorViewAdaptor { TokenSelectorViewAdaptor {
id: assetsSelectorViewAdaptor id: assetsSelectorViewAdaptor

View File

@ -206,6 +206,7 @@ Control {
} }
contentItem: ColumnLayout { contentItem: ColumnLayout {
spacing: Theme.halfPadding
StatusBaseText { StatusBaseText {
id: captionText id: captionText
@ -231,6 +232,7 @@ Control {
Layout.preferredHeight: 44 Layout.preferredHeight: 44
padding: 0 padding: 0
leftPadding: 0
background: null background: null
readOnly: !root.interactive readOnly: !root.interactive
@ -286,7 +288,7 @@ Control {
Rectangle { Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 1 Layout.preferredHeight: 1
Layout.bottomMargin: 12 Layout.bottomMargin: 4
color: Theme.palette.directColor8 color: Theme.palette.directColor8
visible: root.dividerVisible visible: root.dividerVisible
} }
@ -363,7 +365,7 @@ Control {
color: Theme.palette.directColor5 color: Theme.palette.directColor5
visible: hoverHandler.hovered visible: hoverHandler.hovered
} }
RowLayout {} Item { Layout.fillWidth: true }
Loader { Loader {
id: bottomRightComponent id: bottomRightComponent
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter