feat(@desktop/wallet): Update network card and routing lines in SendModal
fixes #8714
This commit is contained in:
parent
c50cf988a7
commit
eb2ec7c1af
|
@ -25,11 +25,14 @@ Item {
|
|||
id: card
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
primaryText: "Mainnet"
|
||||
secondaryText: state === "unavailable" ? "No Gas" : "75"
|
||||
secondaryText: state === "unavailable" ? "No Gas" : "75,0000000"
|
||||
tertiaryText: state === "unpreferred" ? "UNPREFERRED" : "BALANCE: " + 250
|
||||
cardIconName: "status"
|
||||
advancedInputText: "75"
|
||||
advancedInputText: "75,0000000"
|
||||
disabledText: "Disabled"
|
||||
onCardLocked: locked = isLocked
|
||||
disableText: "Disable"
|
||||
enableText: "Enable"
|
||||
}
|
||||
|
||||
StatusComboBox {
|
||||
|
@ -87,6 +90,9 @@ Item {
|
|||
advancedMode: card.advancedMode
|
||||
advancedInputText: tokensToSend
|
||||
disabledText: "Disabled"
|
||||
onCardLocked: locked = isLocked
|
||||
disableText: "Disable"
|
||||
enableText: "Enable"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,6 +112,9 @@ Item {
|
|||
advancedMode: card.advancedMode
|
||||
advancedInputText: tokensToReceive
|
||||
disabledText: "Disabled"
|
||||
onCardLocked: locked = isLocked
|
||||
disableText: "Disable"
|
||||
enableText: "Enable"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusCard
|
||||
|
@ -26,6 +28,9 @@ import StatusQ.Controls 0.1
|
|||
tertiaryText: "BALANCE: " + 250
|
||||
cardIconName: "status"
|
||||
advancedMode: false
|
||||
disableText: "Disable"
|
||||
enableText: "enable"
|
||||
maxAdvancedValue: 100
|
||||
}
|
||||
\endqml
|
||||
For a list of components available see StatusQ.
|
||||
|
@ -87,6 +92,16 @@ Rectangle {
|
|||
Used to set Tertiary text in the StatusCard
|
||||
*/
|
||||
property alias tertiaryText: tertiaryText.text
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::disableText
|
||||
Used to set disable text in the StatusCard
|
||||
*/
|
||||
property alias disableText: disableText.text
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::enableText
|
||||
Used to set enableText text in the StatusCard
|
||||
*/
|
||||
property string enableText
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::advancedInputText
|
||||
Used to set text in the StatusInput in advancedMode
|
||||
|
@ -138,7 +153,11 @@ Rectangle {
|
|||
This property exposes the card icon posistion to help draw the network routes
|
||||
*/
|
||||
property real cardIconPosition: layout.y + cardIcon.y + cardIcon.height/2
|
||||
|
||||
/*!
|
||||
\qmlproperty real StatusCard::maxAdvancedValue
|
||||
This property holds the max value in the advanced input that can be entered by the user
|
||||
*/
|
||||
property real maxAdvancedValue
|
||||
/*!
|
||||
\qmlsignal StatusCard::clicked
|
||||
This signal is emitted when the card is clicked
|
||||
|
@ -162,126 +181,178 @@ Rectangle {
|
|||
*/
|
||||
state: "default"
|
||||
|
||||
implicitHeight: advancedInput.visible ? 90 : 76
|
||||
implicitWidth: 128
|
||||
implicitHeight: 90
|
||||
implicitWidth: 160
|
||||
radius: 8
|
||||
border.width: 1
|
||||
border.color: Theme.palette.primaryColor2
|
||||
|
||||
// This is used to create a shadow around the rectangle when hovered
|
||||
// it was needed to be done this way because it doesnt work with the
|
||||
// main rect when it is transparent in its "default" state
|
||||
Rectangle {
|
||||
id: dummyRect
|
||||
anchors.fill: parent
|
||||
radius: root.radius
|
||||
opacity: 0
|
||||
}
|
||||
DropShadow {
|
||||
anchors.fill: dummyRect
|
||||
verticalOffset: 0
|
||||
horizontalOffset: 0
|
||||
radius: 8
|
||||
samples: 17
|
||||
source: dummyRect
|
||||
color: Theme.palette.dropShadow
|
||||
visible: sensor.containsMouse
|
||||
z: root.z - 1
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: sensor
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton
|
||||
hoverEnabled: true
|
||||
enabled: root.clickable && root.state !== "unavailable"
|
||||
onClicked: {
|
||||
disabled = !disabled
|
||||
if(!advancedMode)
|
||||
disabled = !disabled
|
||||
root.clicked()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
spacing: 0
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.leftMargin: 8
|
||||
anchors.rightMargin: 8
|
||||
anchors.topMargin: 8
|
||||
ColumnLayout {
|
||||
Layout.maximumWidth: root.width - cardIcon.width - 24
|
||||
RowLayout {
|
||||
Layout.preferredWidth: layout.width
|
||||
StatusBaseText {
|
||||
id: primaryText
|
||||
Layout.maximumWidth: parent.width
|
||||
Layout.maximumWidth: layout.width - cardIcon.width - 24
|
||||
font.pixelSize: 15
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
lineHeight: 22
|
||||
lineHeightMode: Text.FixedHeight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
RowLayout {
|
||||
id: basicInput
|
||||
StatusBaseText {
|
||||
id: secondaryLabel
|
||||
Layout.maximumWidth: root.width - cardIcon.width - errorIcon.width - 24
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: 13
|
||||
font.weight: Font.Medium
|
||||
}
|
||||
StatusIcon {
|
||||
id: errorIcon
|
||||
width: 14
|
||||
height: 14
|
||||
Layout.alignment: Qt.AlignTop
|
||||
icon: "tiny/warning"
|
||||
color: Theme.palette.pinColor1
|
||||
}
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: advancedInput
|
||||
property bool tempLock: false
|
||||
implicitWidth: 80
|
||||
maximumHeight: 32
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
leftPadding: 8
|
||||
rightPadding: 5
|
||||
input.edit.font.pixelSize: 13
|
||||
input.edit.readOnly: disabled
|
||||
input.rightComponent: Row {
|
||||
width: implicitWidth
|
||||
spacing: 4
|
||||
StatusFlatRoundButton {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 12
|
||||
height: 12
|
||||
icon.name: root.locked && advancedInput.tempLock ? "lock" : "unlock"
|
||||
icon.width: 12
|
||||
icon.height: 12
|
||||
icon.color: root.locked && advancedInput.tempLock? Theme.palette.primaryColor1 : Theme.palette.baseColor1
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
enabled: !disabled
|
||||
onClicked: {
|
||||
advancedInput.tempLock = !advancedInput.tempLock
|
||||
root.cardLocked(advancedInput.tempLock)
|
||||
}
|
||||
}
|
||||
StatusFlatRoundButton {
|
||||
width: 14
|
||||
height: 14
|
||||
icon.name: "clear"
|
||||
icon.width: 14
|
||||
icon.height: 14
|
||||
icon.color: Theme.palette.baseColor1
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
onClicked: advancedInput.input.edit.clear()
|
||||
}
|
||||
}
|
||||
text: root.preCalculatedAdvancedText
|
||||
onTextChanged: {
|
||||
advancedInput.tempLock = false
|
||||
waitTimer.restart()
|
||||
}
|
||||
Timer {
|
||||
id: waitTimer
|
||||
interval: lockTimeout
|
||||
onTriggered: {
|
||||
advancedInput.tempLock = true
|
||||
if(!!advancedInput.text && root.preCalculatedAdvancedText !== advancedInput.text) {
|
||||
root.cardLocked(advancedInput.tempLock)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusBaseText {
|
||||
id: tertiaryText
|
||||
Layout.maximumWidth: root.width - 12
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: 10
|
||||
StatusIcon {
|
||||
id: cardIcon
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignRight
|
||||
Layout.preferredHeight: 16
|
||||
Layout.preferredWidth: 16
|
||||
mipmap: true
|
||||
}
|
||||
}
|
||||
StatusIcon {
|
||||
id: cardIcon
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignRight
|
||||
RowLayout {
|
||||
id: basicInput
|
||||
Layout.preferredHeight: 32
|
||||
Layout.preferredWidth: 32
|
||||
mipmap: true
|
||||
StatusBaseText {
|
||||
id: secondaryLabel
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: 13
|
||||
lineHeight: 18
|
||||
lineHeightMode: Text.FixedHeight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
StatusIcon {
|
||||
id: errorIcon
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
width: 14
|
||||
height: 14
|
||||
icon: "tiny/warning"
|
||||
color: Theme.palette.pinColor1
|
||||
}
|
||||
}
|
||||
StatusInput {
|
||||
id: advancedInput
|
||||
property bool tempLock: false
|
||||
Layout.preferredWidth: layout.width
|
||||
maximumHeight: 32
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
leftPadding: 8
|
||||
rightPadding: 5
|
||||
input.edit.font.pixelSize: 13
|
||||
input.edit.readOnly: disabled
|
||||
input.background.radius: 4
|
||||
input.background.color: input.edit.activeFocus ? "transparent" : Theme.palette.directColor8
|
||||
input.background.border.color: input.edit.activeFocus ? Theme.palette.primaryColor2 : "transparent"
|
||||
input.rightComponent: Row {
|
||||
width: implicitWidth
|
||||
spacing: 4
|
||||
visible: root.state !== "error"
|
||||
StatusFlatRoundButton {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 12
|
||||
height: 12
|
||||
icon.name: root.locked && advancedInput.tempLock ? "lock" : "unlock"
|
||||
icon.width: 12
|
||||
icon.height: 12
|
||||
icon.color: root.locked && advancedInput.tempLock ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
enabled: !disabled
|
||||
onClicked: {
|
||||
advancedInput.tempLock = !advancedInput.tempLock
|
||||
root.locked = advancedInput.tempLock
|
||||
root.cardLocked(advancedInput.tempLock)
|
||||
}
|
||||
}
|
||||
}
|
||||
validators: [
|
||||
StatusFloatValidator {
|
||||
id: floatValidator
|
||||
bottom: 0
|
||||
top: root.maxAdvancedValue
|
||||
errorMessage: ""
|
||||
}
|
||||
]
|
||||
text: root.preCalculatedAdvancedText
|
||||
onTextChanged: {
|
||||
advancedInput.tempLock = false
|
||||
waitTimer.restart()
|
||||
}
|
||||
Timer {
|
||||
id: waitTimer
|
||||
interval: lockTimeout
|
||||
onTriggered: {
|
||||
advancedInput.tempLock = true
|
||||
if(!!advancedInput.text && root.preCalculatedAdvancedText !== advancedInput.text) {
|
||||
root.locked = advancedInput.tempLock
|
||||
root.cardLocked(advancedInput.tempLock)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusBaseText {
|
||||
id: tertiaryText
|
||||
Layout.maximumWidth: layout.width
|
||||
Layout.preferredHeight: 20
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: 10
|
||||
lineHeight: 14
|
||||
lineHeightMode: Text.FixedHeight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
StatusBaseText {
|
||||
id: disableText
|
||||
Layout.maximumWidth: layout.width
|
||||
Layout.preferredHeight: 20
|
||||
elide: Text.ElideRight
|
||||
font.weight: Font.Medium
|
||||
color: Theme.palette.primaryColor1
|
||||
font.pixelSize: 13
|
||||
lineHeight: 18
|
||||
lineHeightMode: Text.FixedHeight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,7 +365,7 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: root
|
||||
border.color: disabled ? "transparent" : Theme.palette.primaryColor2
|
||||
border.color: Theme.palette.primaryColor2
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
|
@ -306,7 +377,9 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
color: disabled ? Theme.palette.directColor5: Theme.palette.primaryColor1
|
||||
color: disabled ? sensor.containsMouse ?
|
||||
Theme.palette.primaryColor1 :
|
||||
Theme.palette.directColor5: Theme.palette.primaryColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
|
@ -314,7 +387,11 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
text: disabled ? disabledText : secondaryText
|
||||
text: disabled ? sensor.containsMouse ? root.enableText : disabledText : secondaryText
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
font.weight: disabled && sensor.containsMouse ? Font.Medium : Font.Normal
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
|
@ -322,7 +399,11 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
visible: tertiaryText.text
|
||||
visible: advancedMode ? tertiaryText.text : (!sensor.containsMouse && tertiaryText.text) || disabled
|
||||
}
|
||||
PropertyChanges {
|
||||
target: disableText
|
||||
visible: sensor.containsMouse && !advancedMode && !disabled
|
||||
}
|
||||
PropertyChanges {
|
||||
target: cardIcon
|
||||
|
@ -338,7 +419,8 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
input.edit.color: Theme.palette.directColor1
|
||||
input.edit.color: input.edit.activeFocus || !root.locked ?
|
||||
Theme.palette.directColor1 : Theme.palette.directColor5
|
||||
}
|
||||
PropertyChanges {
|
||||
target: basicInput
|
||||
|
@ -353,7 +435,7 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: root
|
||||
border.color: disabled ? "transparent" : Theme.palette.primaryColor2
|
||||
border.color: Theme.palette.primaryColor2
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
|
@ -365,7 +447,9 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
color: disabled ? Theme.palette.directColor5: Theme.palette.dangerColor1
|
||||
color: disabled ? sensor.containsMouse ?
|
||||
Theme.palette.primaryColor1 :
|
||||
Theme.palette.directColor5: Theme.palette.dangerColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
|
@ -373,7 +457,11 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
text: disabled ? disabledText : secondaryText
|
||||
text: disabled ? sensor.containsMouse ? root.enableText : disabledText : secondaryText
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
font.weight: disabled && sensor.containsMouse ? Font.Medium : Font.Normal
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
|
@ -381,7 +469,11 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
visible: tertiaryText.text
|
||||
visible: advancedMode ? tertiaryText.text : (!sensor.containsMouse && tertiaryText.text) || disabled
|
||||
}
|
||||
PropertyChanges {
|
||||
target: disableText
|
||||
visible: sensor.containsMouse && !advancedMode && !disabled
|
||||
}
|
||||
PropertyChanges {
|
||||
target: cardIcon
|
||||
|
@ -397,7 +489,7 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
input.edit.color: disabled ? Theme.palette.directColor5 : Theme.palette.dangerColor1
|
||||
input.edit.color: Theme.palette.dangerColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: basicInput
|
||||
|
@ -412,7 +504,7 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: root
|
||||
border.color: disabled ? "transparent": Theme.palette.pinColor2
|
||||
border.color: Theme.palette.pinColor2
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
|
@ -424,7 +516,9 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
color: disabled ? Theme.palette.directColor5 : Theme.palette.pinColor1
|
||||
color: disabled ? sensor.containsMouse ?
|
||||
Theme.palette.primaryColor1 :
|
||||
Theme.palette.directColor5 : Theme.palette.pinColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
|
@ -432,15 +526,23 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
text: disabled ? disabledText : secondaryText
|
||||
text: disabled ? sensor.containsMouse ? root.enableText : disabledText : secondaryText
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
font.weight: disabled && sensor.containsMouse ? Font.Medium : Font.Normal
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
color: disabled ? Theme.palette.directColor5 : Theme.palette.pinColor1
|
||||
color: Theme.palette.pinColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
visible: tertiaryText.text
|
||||
visible: advancedMode ? tertiaryText.text : (!sensor.containsMouse && tertiaryText.text) || disabled
|
||||
}
|
||||
PropertyChanges {
|
||||
target: disableText
|
||||
visible: sensor.containsMouse && !advancedMode && !disabled
|
||||
}
|
||||
PropertyChanges {
|
||||
target: cardIcon
|
||||
|
@ -456,7 +558,7 @@ Rectangle {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
input.edit.color: Theme.palette.directColor1
|
||||
input.edit.color: root.locked ? Theme.palette.directColor5 : Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: basicInput
|
||||
|
@ -493,13 +595,21 @@ Rectangle {
|
|||
target: secondaryLabel
|
||||
text: secondaryText
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
font.weight: disabled && sensor.containsMouse ? Font.Medium : Font.Normal
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
color: Theme.palette.directColor5
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
visible: tertiaryText.text
|
||||
visible: advancedMode ? tertiaryText.text : (!sensor.containsMouse && tertiaryText.text) || disabled
|
||||
}
|
||||
PropertyChanges {
|
||||
target: disableText
|
||||
visible: sensor.containsMouse && !advancedMode && !disabled
|
||||
}
|
||||
PropertyChanges {
|
||||
target: cardIcon
|
||||
|
|
|
@ -82,72 +82,75 @@ QtObject {
|
|||
|
||||
// function to draw arrow
|
||||
function drawArrow(context, fromx, fromy, tox, toy, color, offset) {
|
||||
const dx = tox - fromx;
|
||||
const fromX = fromx + 8
|
||||
const toX = tox - 8
|
||||
const dx = toX - fromX;
|
||||
const dy = toy - fromy;
|
||||
const headlen = 10; // length of head in pixels
|
||||
const headlen = 8; // length of head in pixels
|
||||
const angle = 0
|
||||
const radius = 5
|
||||
const radius = 4
|
||||
|
||||
context.strokeStyle = color ? color : '#627EEA'
|
||||
|
||||
// straight line
|
||||
if(dy === 0) {
|
||||
// draw semicircle
|
||||
// draw circle
|
||||
context.setLineDash([20,0])
|
||||
context.beginPath()
|
||||
context.arc(fromx, fromy, radius, 3*Math.PI/2, Math.PI/2,false)
|
||||
context.arc(fromX+radius, fromy, radius, 0, 360)
|
||||
context.stroke()
|
||||
|
||||
// draw straightline
|
||||
context.setLineDash([3])
|
||||
context.beginPath()
|
||||
context.moveTo(fromx + radius, fromy)
|
||||
context.lineTo(tox, toy)
|
||||
context.moveTo(fromX + 2*radius, fromy)
|
||||
context.lineTo(toX, toy)
|
||||
context.stroke()
|
||||
|
||||
// draw arrow
|
||||
context.setLineDash([10,0])
|
||||
context.setLineDash([20,0])
|
||||
context.beginPath()
|
||||
context.moveTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6))
|
||||
context.lineTo(tox, toy )
|
||||
context.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6))
|
||||
context.moveTo(toX - headlen * Math.cos(angle - Math.PI / 4), toy - headlen * Math.sin(angle - Math.PI / 4))
|
||||
context.lineTo(toX, toy)
|
||||
context.lineTo(toX - headlen * Math.cos(angle + Math.PI / 4), toy - headlen * Math.sin(angle + Math.PI / 4))
|
||||
context.stroke()
|
||||
}
|
||||
// connecting between 2 different y positions
|
||||
else {
|
||||
|
||||
// draw semicircle
|
||||
// draw circle
|
||||
context.setLineDash([20,0])
|
||||
context.beginPath()
|
||||
context.arc(fromx, fromy, radius, 3*Math.PI/2, Math.PI/2,false)
|
||||
context.arc(fromX+radius, fromy, radius, 0, 360)
|
||||
context.stroke()
|
||||
|
||||
// draw bent line
|
||||
context.setLineDash([3])
|
||||
context.beginPath()
|
||||
context.moveTo(fromx + radius, fromy)
|
||||
context.lineTo(fromx + dx / 2 - offset, fromy)
|
||||
context.lineTo(fromx + dx / 2 - offset, toy + (dy < 0 ? radius : -radius))
|
||||
context.moveTo(fromX + 2*radius, fromy)
|
||||
context.lineTo(fromX + dx / 2 - offset, fromy)
|
||||
context.lineTo(fromX + dx / 2 - offset, toy + (dy < 0 ? radius : -radius))
|
||||
context.stroke()
|
||||
|
||||
// draw connecting circle
|
||||
context.setLineDash([10,0])
|
||||
context.setLineDash([20,0])
|
||||
context.beginPath()
|
||||
context.moveTo(fromx + dx / 2 + radius - offset, toy)
|
||||
context.arc(fromx + dx / 2 - offset, toy, radius, 0, 2*Math.PI,false)
|
||||
context.moveTo(fromX + dx / 2 + radius - offset, toy)
|
||||
context.arc(fromX + dx / 2 - offset, toy, radius, 0, 2*Math.PI,false)
|
||||
context.stroke()
|
||||
|
||||
// draw straightline
|
||||
context.setLineDash([3])
|
||||
context.beginPath()
|
||||
context.moveTo(fromx + dx / 2 + radius - offset, toy);
|
||||
context.lineTo(tox, toy)
|
||||
context.moveTo(fromX + dx / 2 + 2*radius - offset, toy);
|
||||
context.lineTo(toX, toy)
|
||||
context.stroke()
|
||||
|
||||
// draw arrow
|
||||
context.setLineDash([10,0])
|
||||
context.setLineDash([20,0])
|
||||
context.beginPath()
|
||||
context.moveTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6))
|
||||
context.lineTo(tox, toy )
|
||||
context.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6))
|
||||
context.moveTo(toX - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6))
|
||||
context.lineTo(toX, toy )
|
||||
context.lineTo(toX - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6))
|
||||
context.stroke()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ import StatusQ.Core.Theme 0.1
|
|||
ColumnLayout {
|
||||
id: balancedExceededError
|
||||
|
||||
property bool transferPossible: false
|
||||
property double amountToSend: 0
|
||||
property bool isLoading: true
|
||||
property int errorType: Constants.NoError
|
||||
|
||||
visible: !balancedExceededError.transferPossible || isLoading
|
||||
visible: balancedExceededError.errorType !== Constants.NoError || isLoading
|
||||
|
||||
StatusIcon {
|
||||
Layout.preferredHeight: 20
|
||||
|
@ -35,12 +35,14 @@ ColumnLayout {
|
|||
visible: isLoading
|
||||
}
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
font.pixelSize: 13
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: Theme.palette.dangerColor1
|
||||
text: isLoading ? qsTr("Calculating fees") : qsTr("Balance exceeded")
|
||||
text: isLoading ? qsTr("Calculating fees") : balancedExceededError.errorType === Constants.SendAmountExceedsBalance ?
|
||||
qsTr("Balance exceeded") : balancedExceededError.errorType === Constants.NoRoute ? qsTr("No route found") : ""
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,32 +13,37 @@ import "../panels"
|
|||
Column {
|
||||
id: root
|
||||
|
||||
visible: !isValid || isLoading
|
||||
spacing: 5
|
||||
|
||||
property alias errorMessage: txtValidationError.text
|
||||
property bool isValid: true
|
||||
property int errorType: Constants.NoError
|
||||
property bool isLoading: false
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
readonly property bool isValid: root.errorType === Constants.NoError
|
||||
}
|
||||
|
||||
visible: !d.isValid || isLoading
|
||||
spacing: 5
|
||||
|
||||
StatusIcon {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: 20
|
||||
width: 20
|
||||
icon: "cancel"
|
||||
color: Theme.palette.dangerColor1
|
||||
visible: !isValid && !isLoading
|
||||
visible: !d.isValid && !isLoading
|
||||
}
|
||||
StatusLoadingIndicator {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 24
|
||||
height: 24
|
||||
color: Theme.palette.baseColor1
|
||||
visible: isLoading && isValid
|
||||
visible: isLoading && d.isValid
|
||||
}
|
||||
StyledText {
|
||||
id: txtValidationError
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: isLoading? qsTr("Calculating fees"): qsTr("Balance exceeded")
|
||||
text: isLoading ? qsTr("Calculating fees"): errorType === Constants.SendAmountExceedsBalance ?
|
||||
qsTr("Balance exceeded") : qsTr("No route found")
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: 13
|
||||
|
|
|
@ -67,7 +67,7 @@ StatusDialog {
|
|||
}
|
||||
|
||||
property var recalculateRoutesAndFees: Backpressure.debounce(popup, 600, function() {
|
||||
if(!!popup.selectedAccount && !!assetSelector.selectedAsset && d.recipientReady) {
|
||||
if(!!popup.selectedAccount && !!assetSelector.selectedAsset && d.recipientReady && amountToSendInput.input.valid) {
|
||||
popup.isLoading = true
|
||||
let amount = Math.round(parseFloat(amountToSendInput.cryptoValueToSend) * Math.pow(10, assetSelector.selectedAsset.decimals))
|
||||
popup.store.suggestedRoutes(popup.selectedAccount.address, amount.toString(16), assetSelector.selectedAsset.symbol,
|
||||
|
@ -78,15 +78,13 @@ StatusDialog {
|
|||
|
||||
QtObject {
|
||||
id: d
|
||||
readonly property int errorType: !amountToSendInput.input.valid ? Constants.SendAmountExceedsBalance :
|
||||
(networkSelector.bestRoutes && networkSelector.bestRoutes.length <= 0 && !!amountToSendInput.input.text && recipientReady && !popup.isLoading) ?
|
||||
Constants.NoRoute : Constants.NoError
|
||||
readonly property double maxFiatBalance: !!assetSelector.selectedAsset ? (amountToSendInput.cryptoFiatFlipped ?
|
||||
assetSelector.selectedAsset.totalCurrencyBalance :
|
||||
assetSelector.selectedAsset.totalBalance): 0
|
||||
onMaxFiatBalanceChanged: {
|
||||
amountToSendInput.floatValidator.top = maxFiatBalance
|
||||
amountToSendInput.input.validate()
|
||||
}
|
||||
readonly property bool isReady: amountToSendInput.input.valid && !amountToSendInput.input.pending && recipientReady
|
||||
readonly property bool errorMode: popup.isLoading || !isReady ? false : (networkSelector.bestRoutes && networkSelector.bestRoutes.length <= 0) || networkSelector.errorMode || isNaN(amountToSendInput.input.text)
|
||||
readonly property bool errorMode: popup.isLoading || !recipientReady ? false : errorType !== Constants.NoError || networkSelector.errorMode || isNaN(amountToSendInput.input.text)
|
||||
readonly property bool recipientReady: (isAddressValid || isENSValid) && !recipientSelector.isPending
|
||||
property bool isAddressValid: Utils.isValidAddress(popup.addressText)
|
||||
property bool isENSValid: false
|
||||
|
@ -110,6 +108,11 @@ StatusDialog {
|
|||
popup.recalculateRoutesAndFees()
|
||||
}
|
||||
}
|
||||
|
||||
onErrorTypeChanged: {
|
||||
if(errorType === Constants.SendAmountExceedsBalance)
|
||||
bestRoutes = []
|
||||
}
|
||||
}
|
||||
|
||||
width: 556
|
||||
|
@ -230,7 +233,7 @@ StatusDialog {
|
|||
return ""
|
||||
}
|
||||
onSelectedAssetChanged: {
|
||||
if (!assetSelector.selectedAsset || !!amountToSendInput.input.text || isNaN(amountToSendInput.input.text)) {
|
||||
if (!assetSelector.selectedAsset || !amountToSendInput.input.text || isNaN(amountToSendInput.input.text)) {
|
||||
return
|
||||
}
|
||||
popup.recalculateRoutesAndFees()
|
||||
|
@ -242,8 +245,8 @@ StatusDialog {
|
|||
title: d.maxFiatBalance > 0 ? qsTr("Max: %1").arg(LocaleUtils.numberToLocaleString(d.maxFiatBalance)) : qsTr("No balances active")
|
||||
closeButtonVisible: false
|
||||
titleText.font.pixelSize: 12
|
||||
bgColor: d.errorMode ? Theme.palette.dangerColor2 : Theme.palette.primaryColor3
|
||||
titleText.color: d.errorMode ? Theme.palette.dangerColor1 : Theme.palette.primaryColor1
|
||||
bgColor: amountToSendInput.input.valid ? Theme.palette.primaryColor3 : Theme.palette.dangerColor2
|
||||
titleText.color: amountToSendInput.input.valid ? Theme.palette.primaryColor1 : Theme.palette.dangerColor1
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
|
@ -253,10 +256,15 @@ StatusDialog {
|
|||
Layout.fillWidth:true
|
||||
isBridgeTx: popup.isBridgeTx
|
||||
interactive: popup.interactive
|
||||
store: popup.store
|
||||
selectedAsset: assetSelector.selectedAsset
|
||||
errorMode: d.errorMode
|
||||
maxFiatBalance: d.maxFiatBalance
|
||||
currentCurrency: popup.store.currentCurrency
|
||||
getFiatValue: function(cryptoValue) {
|
||||
return popup.store.getFiatValue(cryptoValue, selectedAsset.symbol, currentCurrency)
|
||||
}
|
||||
getCryptoValue: function(fiatValue) {
|
||||
return popup.store.getFiatValue(fiatValue, selectedAsset.symbol, currentCurrency)
|
||||
}
|
||||
onReCalculateSuggestedRoute: popup.recalculateRoutesAndFees()
|
||||
}
|
||||
AmountToReceive {
|
||||
|
@ -405,7 +413,7 @@ StatusDialog {
|
|||
selectedAsset: assetSelector.selectedAsset
|
||||
onReCalculateSuggestedRoute: popup.recalculateRoutesAndFees()
|
||||
visible: d.recipientReady && !!assetSelector.selectedAsset
|
||||
|
||||
errorType: d.errorType
|
||||
isLoading: popup.isLoading
|
||||
bestRoutes: popup.bestRoutes
|
||||
isBridgeTx: popup.isBridgeTx
|
||||
|
@ -424,6 +432,7 @@ StatusDialog {
|
|||
bestRoutes: popup.bestRoutes
|
||||
store: popup.store
|
||||
gasFiatAmount: d.totalFeesInFiat
|
||||
errorType: d.errorType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -435,7 +444,7 @@ StatusDialog {
|
|||
maxFiatFees: popup.isLoading ? "..." : "%1 %2".arg(LocaleUtils.numberToLocaleString(d.totalFeesInFiat)).arg(popup.store.currentCurrency.toUpperCase())
|
||||
totalTimeEstimate: popup.isLoading? "..." : d.totalTimeEstimate
|
||||
pending: d.isPendingTx || popup.isLoading
|
||||
visible: d.isReady && !isNaN(amountToSendInput.cryptoValueToSend) && fees.isValid && !d.errorMode
|
||||
visible: d.recipientReady && !isNaN(amountToSendInput.cryptoValueToSend) && !d.errorMode
|
||||
onNextButtonClicked: popup.sendTransaction()
|
||||
}
|
||||
|
||||
|
|
|
@ -13,16 +13,16 @@ ColumnLayout {
|
|||
id: root
|
||||
|
||||
property alias input: amountToSendInput
|
||||
property alias floatValidator: floatValidator
|
||||
|
||||
property var store
|
||||
property var selectedAsset
|
||||
property bool errorMode
|
||||
property bool isBridgeTx: false
|
||||
property bool interactive: false
|
||||
property double maxFiatBalance
|
||||
property double maxFiatBalance: -1
|
||||
property bool cryptoFiatFlipped: false
|
||||
property string cryptoValueToSend: !cryptoFiatFlipped ? amountToSendInput.text : txtFiatBalance.text
|
||||
property string currentCurrency
|
||||
property var getFiatValue: function(cryptoValue) {}
|
||||
property var getCryptoValue: function(fiatValue) {}
|
||||
|
||||
signal reCalculateSuggestedRoute()
|
||||
|
||||
|
@ -40,13 +40,13 @@ ColumnLayout {
|
|||
function getFiatValue(value) {
|
||||
if(!root.selectedAsset || !value)
|
||||
return zeroString
|
||||
let cryptoValue = root.store.getFiatValue(value, root.selectedAsset.symbol, root.store.currentCurrency)
|
||||
let cryptoValue = root.getFiatValue(value)
|
||||
return formatValue(parseFloat(cryptoValue))
|
||||
}
|
||||
function getCryptoValue(value) {
|
||||
if(!root.selectedAsset || !value)
|
||||
return zeroString
|
||||
let cryptoValue = root.store.getCryptoValue(value, root.selectedAsset.symbol, root.store.currentCurrency)
|
||||
let cryptoValue = root.getCryptoValue(value)
|
||||
return formatValue(parseFloat(cryptoValue))
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,11 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
onMaxFiatBalanceChanged: {
|
||||
floatValidator.top = maxFiatBalance
|
||||
input.validate()
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
text: root.isBridgeTx ? qsTr("Amount to bridge") : qsTr("Amount to send")
|
||||
|
@ -73,7 +78,7 @@ ColumnLayout {
|
|||
Layout.maximumWidth: 163
|
||||
Layout.preferredWidth: (!!text) ? input.edit.paintedWidth : textMetrics.advanceWidth
|
||||
placeholderText: d.zeroString
|
||||
input.edit.color: root.errorMode ? Theme.palette.dangerColor1 : Theme.palette.directColor1
|
||||
input.edit.color: input.valid ? Theme.palette.directColor1 : Theme.palette.dangerColor1
|
||||
input.edit.readOnly: !root.interactive
|
||||
validators: [
|
||||
StatusFloatValidator {
|
||||
|
@ -99,7 +104,7 @@ ColumnLayout {
|
|||
}
|
||||
StatusBaseText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: root.store.currentCurrency.toUpperCase()
|
||||
text: root.currentCurrency.toUpperCase()
|
||||
font.pixelSize: amountToSendInput.input.edit.font.pixelSize
|
||||
color: Theme.palette.baseColor1
|
||||
visible: cryptoFiatFlipped
|
||||
|
@ -123,7 +128,7 @@ ColumnLayout {
|
|||
anchors.top: parent.top
|
||||
anchors.left: txtFiatBalance.right
|
||||
anchors.leftMargin: 4
|
||||
text: !cryptoFiatFlipped ? root.store.currentCurrency.toUpperCase() : !!root.selectedAsset ? root.selectedAsset.symbol.toUpperCase() : ""
|
||||
text: !cryptoFiatFlipped ? root.currentCurrency.toUpperCase() : !!root.selectedAsset ? root.selectedAsset.symbol.toUpperCase() : ""
|
||||
font.pixelSize: 13
|
||||
color: Theme.palette.directColor5
|
||||
}
|
||||
|
|
|
@ -12,13 +12,12 @@ import "../controls"
|
|||
Rectangle {
|
||||
id: root
|
||||
|
||||
property alias isValid: gasValidator.isValid
|
||||
|
||||
property string gasFiatAmount
|
||||
property bool isLoading: false
|
||||
property var bestRoutes
|
||||
property var store
|
||||
property var selectedTokenSymbol
|
||||
property int errorType: Constants.NoError
|
||||
|
||||
radius: 13
|
||||
color: Theme.palette.indirectColor1
|
||||
|
@ -70,7 +69,7 @@ Rectangle {
|
|||
getFiatValue: root.store.getFiatValue
|
||||
currentCurrency: root.store.currencyStore.currentCurrency
|
||||
currentCurrencySymbol: root.store.currencyStore.currentCurrencySymbol
|
||||
visible: gasValidator.isValid && !root.isLoading
|
||||
visible: root.errorType === Constants.NoError && !root.isLoading
|
||||
bestRoutes: root.bestRoutes
|
||||
selectedTokenSymbol: root.selectedTokenSymbol
|
||||
}
|
||||
|
@ -78,7 +77,7 @@ Rectangle {
|
|||
id: gasValidator
|
||||
width: parent.width
|
||||
isLoading: root.isLoading
|
||||
isValid: root.bestRoutes ? root.bestRoutes.length > 0 : true
|
||||
errorType: root.errorType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ import StatusQ.Core 0.1
|
|||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||
|
||||
import "../controls"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
|
@ -21,11 +23,13 @@ Item {
|
|||
property bool customMode: false
|
||||
property double amountToSend: 0
|
||||
property double requiredGasInEth: 0
|
||||
property bool errorMode: !d.thereIsApossibleRoute || d.customAmountToSend > root.amountToSend
|
||||
property bool errorMode: d.customAmountToSend > root.amountToSend
|
||||
property bool interactive: true
|
||||
property bool showPreferredChains: false
|
||||
property var weiToEth: function(wei) {}
|
||||
property var reCalculateSuggestedRoute: function() {}
|
||||
property int errorType: Constants.NoError
|
||||
property bool isLoading
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
@ -38,6 +42,7 @@ Item {
|
|||
fromNetworksRepeater.itemAt(i).routeOnNetwork = 0
|
||||
toNetworksRepeater.itemAt(i).amountToReceive = 0
|
||||
toNetworksRepeater.itemAt(i).routeOnNetwork = 0
|
||||
toNetworksRepeater.itemAt(i).bentLine = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,6 +77,8 @@ Item {
|
|||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
spacing: 12
|
||||
StatusBaseText {
|
||||
Layout.maximumWidth: 100
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: 10
|
||||
color: Theme.palette.baseColor1
|
||||
text: qsTr("Your Balances").toUpperCase()
|
||||
|
@ -90,7 +97,7 @@ Item {
|
|||
primaryText: model.chainName
|
||||
secondaryText: (parseFloat(tokenBalanceOnChain) === 0 && root.amountToSend !== 0) ?
|
||||
qsTr("No Balance") : !hasGas ? qsTr("No Gas") : advancedInputText
|
||||
tertiaryText: qsTr("BALANCE: ") + LocaleUtils.numberToLocaleString(parseFloat(tokenBalanceOnChain))
|
||||
tertiaryText: root.errorMode && parseFloat(advancedInputText) !== 0 && advancedInput.valid ? qsTr("EXCEEDS SEND AMOUNT"): qsTr("BALANCE: ") + LocaleUtils.numberToLocaleString(parseFloat(tokenBalanceOnChain))
|
||||
locked: store.lockedInAmounts.findIndex(lockedItem => lockedItem !== undefined && lockedItem.chainID === model.chainId) !== -1
|
||||
preCalculatedAdvancedText: {
|
||||
let index = store.lockedInAmounts.findIndex(lockedItem => lockedItem!== undefined && lockedItem.chainID === model.chainId)
|
||||
|
@ -99,9 +106,14 @@ Item {
|
|||
}
|
||||
else return LocaleUtils.numberToLocaleString(fromNetwork.amountToSend)
|
||||
}
|
||||
state: tokenBalanceOnChain === 0 || !hasGas ? "unavailable" : root.errorMode ? "error" : "default"
|
||||
maxAdvancedValue: parseFloat(tokenBalanceOnChain)
|
||||
state: tokenBalanceOnChain === 0 || !hasGas ?
|
||||
"unavailable" :
|
||||
(root.errorMode || !advancedInput.valid) && (parseFloat(advancedInputText) !== 0) ? "error" : "default"
|
||||
cardIcon.source: Style.svg(model.iconUrl)
|
||||
disabledText: qsTr("Disabled")
|
||||
disableText: qsTr("Disable")
|
||||
enableText: qsTr("Enable")
|
||||
advancedMode: root.customMode
|
||||
disabled: store.disabledChainIdsFromList.includes(model.chainId)
|
||||
clickable: root.interactive
|
||||
|
@ -116,17 +128,24 @@ Item {
|
|||
disabled = store.disabledChainIdsFromList.includes(model.chainId)
|
||||
}
|
||||
onCardLocked: {
|
||||
|
||||
store.addLockedInAmount(model.chainId, advancedInputText, root.selectedAsset.decimals, isLocked)
|
||||
locked = store.lockedInAmounts.length > 0 && store.lockedInAmounts.findIndex(lockedItem => lockedItem !== undefined && lockedItem.chainID === model.chainId) !== -1
|
||||
d.calculateCustomAmounts()
|
||||
if(!locked || d.customAmountToSend <= root.amountToSend)
|
||||
if(!locked || (d.customAmountToSend <= root.amountToSend && advancedInput.valid))
|
||||
root.reCalculateSuggestedRoute()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BalanceExceeded {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
amountToSend: root.amountToSend
|
||||
isLoading: root.isLoading
|
||||
errorType: root.errorType
|
||||
}
|
||||
ColumnLayout {
|
||||
id: toMainNetworksLayout
|
||||
id: toNetworksLayout
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignTop
|
||||
spacing: 12
|
||||
StatusBaseText {
|
||||
|
@ -137,47 +156,46 @@ Item {
|
|||
text: StatusQUtils.Utils.elideText(selectedAccount.address, 6, 4).toUpperCase()
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
Column {
|
||||
id: toNetworksLayout
|
||||
spacing: root.customMode ? 26 : 12
|
||||
Repeater {
|
||||
id: toNetworksRepeater
|
||||
model: root.allNetworks
|
||||
StatusCard {
|
||||
id: toCard
|
||||
objectName: model.chainId
|
||||
property int routeOnNetwork: 0
|
||||
property double amountToReceive: 0
|
||||
property bool preferred: store.preferredChainIds.includes(model.chainId)
|
||||
primaryText: model.chainName
|
||||
secondaryText: LocaleUtils.numberToLocaleString(amountToReceive)
|
||||
tertiaryText: state === "unpreferred" ? qsTr("UNPREFERRED") : ""
|
||||
state: root.errorMode ? "error" : !preferred ? "unpreferred" : "default"
|
||||
opacity: preferred || showPreferredChains ? 1 : 0
|
||||
cardIcon.source: Style.svg(model.iconUrl)
|
||||
disabledText: qsTr("Disabled")
|
||||
disabled: store.disabledChainIdsToList.includes(model.chainId)
|
||||
clickable: root.interactive
|
||||
onClicked: {
|
||||
store.addRemoveDisabledToChain(model.chainId, disabled)
|
||||
// only recalculate if the a best route was disabled
|
||||
if(root.bestRoutes.length === 0 || routeOnNetwork !== 0 || !disabled)
|
||||
Repeater {
|
||||
id: toNetworksRepeater
|
||||
model: root.allNetworks
|
||||
StatusCard {
|
||||
id: toCard
|
||||
objectName: model.chainId
|
||||
property int routeOnNetwork: 0
|
||||
property int bentLine: 0
|
||||
property double amountToReceive: 0
|
||||
property bool preferred: store.preferredChainIds.includes(model.chainId)
|
||||
primaryText: model.chainName
|
||||
secondaryText: LocaleUtils.numberToLocaleString(amountToReceive)
|
||||
tertiaryText: state === "unpreferred" ? qsTr("UNPREFERRED") : ""
|
||||
state: !preferred ? "unpreferred" : "default"
|
||||
opacity: preferred || showPreferredChains ? 1 : 0
|
||||
cardIcon.source: Style.svg(model.iconUrl)
|
||||
disabledText: qsTr("Disabled")
|
||||
disableText: qsTr("Disable")
|
||||
enableText: qsTr("Enable")
|
||||
disabled: store.disabledChainIdsToList.includes(model.chainId)
|
||||
clickable: root.interactive
|
||||
onClicked: {
|
||||
store.addRemoveDisabledToChain(model.chainId, disabled)
|
||||
// only recalculate if the a best route was disabled
|
||||
if((root.bestRoutes !== undefined && root.bestRoutes.length === 0) || routeOnNetwork !== 0 || !disabled)
|
||||
root.reCalculateSuggestedRoute()
|
||||
}
|
||||
onVisibleChanged: {
|
||||
if(visible) {
|
||||
disabled = store.disabledChainIdsToList.includes(model.chainId)
|
||||
preferred = store.preferredChainIds.includes(model.chainId)
|
||||
}
|
||||
}
|
||||
onOpacityChanged: {
|
||||
if(opacity === 1) {
|
||||
disabled = store.disabledChainIdsToList.includes(model.chainId)
|
||||
} else {
|
||||
if(opacity === 0 && routeOnNetwork > 0)
|
||||
root.reCalculateSuggestedRoute()
|
||||
}
|
||||
onVisibleChanged: {
|
||||
if(visible) {
|
||||
disabled = store.disabledChainIdsToList.includes(model.chainId)
|
||||
preferred = store.preferredChainIds.includes(model.chainId)
|
||||
}
|
||||
}
|
||||
onOpacityChanged: {
|
||||
if(opacity === 1) {
|
||||
disabled = store.disabledChainIdsToList.includes(model.chainId)
|
||||
} else {
|
||||
if(opacity === 0 && routeOnNetwork > 0)
|
||||
root.reCalculateSuggestedRoute()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,20 +246,21 @@ Item {
|
|||
}
|
||||
}
|
||||
if(toN !== null && fromN !== null) {
|
||||
yOffsetFrom = toN.objectName === fromN.objectName && toN.routeOnNetwork !== 0 ? toN.routeOnNetwork * 10 : 0
|
||||
yOffsetTo = toN.routeOnNetwork * 10
|
||||
xOffset = toN.routeOnNetwork * 10
|
||||
yOffsetFrom = toN.objectName === fromN.objectName && toN.routeOnNetwork !== 0 ? toN.routeOnNetwork * 16 : 0
|
||||
yOffsetTo = toN.routeOnNetwork * 16
|
||||
xOffset = (fromN.y - toN.y > 0 ? -1 : 1) * toN.bentLine * 16
|
||||
let amountToSend = weiToEth(bestRoutes[i].amountIn)
|
||||
let amountToReceive = weiToEth(bestRoutes[i].amountOut)
|
||||
fromN.amountToSend = amountToSend
|
||||
toN.amountToReceive += amountToReceive
|
||||
fromN.routeOnNetwork += 1
|
||||
toN.routeOnNetwork += 1
|
||||
toN.bentLine = toN.objectName !== fromN.objectName
|
||||
d.thereIsApossibleRoute = true
|
||||
let routeColor = root.errorMode ? Theme.palette.dangerColor1 : toN.preferred ? '#627EEA' : Theme.palette.pinColor1
|
||||
StatusQUtils.Utils.drawArrow(ctx, fromN.x + fromN.width,
|
||||
fromN.y + fromN.cardIconPosition + yOffsetFrom,
|
||||
toMainNetworksLayout.x + toN.x,
|
||||
toNetworksLayout.x + toN.x,
|
||||
toNetworksLayout.y + toN.y + toN.cardIconPosition + yOffsetTo,
|
||||
routeColor, xOffset)
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ Item {
|
|||
property bool isBridgeTx: false
|
||||
property bool showUnpreferredNetworks: advancedNetworkRoutingPage.showUnpreferredNetworks
|
||||
property var toNetworksList: []
|
||||
property int errorType: Constants.NoError
|
||||
|
||||
signal reCalculateSuggestedRoute()
|
||||
|
||||
|
@ -80,6 +81,7 @@ Item {
|
|||
selectedAsset: root.selectedAsset
|
||||
selectedAccount: root.selectedAccount
|
||||
errorMode: root.errorMode
|
||||
errorType: root.errorType
|
||||
toNetworksList: root.toNetworksList
|
||||
weiToEth: function(wei) {
|
||||
return "%1 %2".arg(LocaleUtils.numberToLocaleString(parseFloat(store.getWei2Eth(wei, selectedAsset.decimals)))).arg(selectedAsset.symbol)
|
||||
|
@ -110,6 +112,7 @@ Item {
|
|||
isLoading: root.isLoading
|
||||
interactive: root.interactive
|
||||
isBridgeTx: root.isBridgeTx
|
||||
errorType: root.errorType
|
||||
weiToEth: function(wei) {
|
||||
return parseFloat(store.getWei2Eth(wei, selectedAsset.decimals))
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ ColumnLayout {
|
|||
property bool interactive: true
|
||||
property bool isBridgeTx: false
|
||||
property bool showUnpreferredNetworks: preferredToggleButton.checked
|
||||
property int errorType: Constants.NoError
|
||||
|
||||
signal reCalculateSuggestedRoute()
|
||||
|
||||
|
@ -74,19 +75,9 @@ ColumnLayout {
|
|||
text: qsTr("The networks where the receipient will receive tokens. Amounts calculated automatically for the lowest cost.")
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
BalanceExceeded {
|
||||
id: balanceExceeded
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: Style.current.bigPadding
|
||||
transferPossible: root.store.disabledChainIdsToList.length > 0 || root.store.disabledChainIdsFromList.length > 0 ? true : root.bestRoutes ? root.bestRoutes.length > 0 : false
|
||||
amountToSend: root.amountToSend
|
||||
isLoading: root.isLoading
|
||||
}
|
||||
Loader {
|
||||
id: networksLoader
|
||||
Layout.topMargin: Style.current.padding
|
||||
active: !balanceExceeded.visible
|
||||
visible: active
|
||||
sourceComponent: NetworkCardsComponent {
|
||||
store: root.store
|
||||
|
@ -103,6 +94,8 @@ ColumnLayout {
|
|||
bestRoutes: root.bestRoutes
|
||||
weiToEth: root.weiToEth
|
||||
interactive: root.interactive
|
||||
errorType: root.errorType
|
||||
isLoading: root.isLoading
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ RowLayout {
|
|||
property var weiToEth: function(wei) {}
|
||||
property var reCalculateSuggestedRoute: function() {}
|
||||
property bool errorMode: false
|
||||
property int errorType: Constants.NoError
|
||||
spacing: 10
|
||||
|
||||
StatusRoundIcon {
|
||||
|
@ -62,7 +63,7 @@ RowLayout {
|
|||
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
|
||||
clip: true
|
||||
visible: !root.isLoading ? root.isBridgeTx ? true : root.bestRoutes !== undefined ? root.bestRoutes.length > 0 : true : false
|
||||
visible: !root.isLoading ? root.isBridgeTx ? true : root.errorType === Constants.NoError : false
|
||||
Column {
|
||||
id: row
|
||||
spacing: Style.current.padding
|
||||
|
@ -78,9 +79,9 @@ RowLayout {
|
|||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: Style.current.bigPadding
|
||||
transferPossible: root.bestRoutes !== undefined ? root.bestRoutes.length > 0 : true
|
||||
amountToSend: root.amountToSend
|
||||
isLoading: root.isLoading
|
||||
errorType: root.errorType
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -725,6 +725,12 @@ QtObject {
|
|||
Bridge
|
||||
}
|
||||
|
||||
enum ErrorType {
|
||||
SendAmountExceedsBalance,
|
||||
NoRoute,
|
||||
NoError
|
||||
}
|
||||
|
||||
readonly property QtObject walletSection: QtObject {
|
||||
readonly property string cancelledMessage: "cancelled"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue