mirror of https://github.com/layters/testshop
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
482 lines
25 KiB
482 lines
25 KiB
import QtQuick 2.12
|
|
import QtQuick.Controls 2.12
|
|
import QtQuick.Layouts 1.12
|
|
import QtGraphicalEffects 1.12
|
|
|
|
import FontAwesome 1.0
|
|
import neroshop.CurrencyExchangeRates 1.0
|
|
|
|
// Wallet page
|
|
import "../../components" as NeroshopComponents
|
|
|
|
Page {
|
|
id: walletSettingsPage
|
|
background: Rectangle {
|
|
color: "transparent"//"#0a0a0a"
|
|
}
|
|
|
|
ColumnLayout {
|
|
id: balanceTxColumn
|
|
anchors.margins: 20
|
|
anchors.fill: parent
|
|
spacing: 30
|
|
//property real numberTextFontSize: 48//24
|
|
property string textColor: (NeroshopComponents.Style.darkTheme) ? "#ffffff" : "#000000"
|
|
property string baseColor: (NeroshopComponents.Style.darkTheme) ? (NeroshopComponents.Style.themeName == "PurpleDust" ? "#0e0e11" : "#101010") : "#f0f0f0"
|
|
property string borderColor: (NeroshopComponents.Style.darkTheme) ? "#404040" : "#4d4d4d"
|
|
property real radius: 15
|
|
|
|
// Balance
|
|
Rectangle {
|
|
id: balanceDisplay
|
|
Layout.fillWidth: true//Layout.preferredWidth: parent.width - 200
|
|
Layout.preferredHeight: 200
|
|
radius: parent.radius//5
|
|
color: balanceTxColumn.baseColor
|
|
border.color: balanceTxColumn.borderColor
|
|
|
|
Column {
|
|
anchors.centerIn: parent
|
|
spacing: 0
|
|
Row {
|
|
spacing: 5
|
|
TextField {
|
|
id: balanceUnlockedText
|
|
visible: (settingsDialog.balanceDisplay == 1) ? false : true
|
|
property double balance: !Wallet.opened ? 0.000000000000 : Wallet.balanceUnlocked
|
|
text: balance.toFixed(settingsDialog.balanceAmountPrecision)
|
|
font.bold: true
|
|
font.pointSize: 48
|
|
color: balanceTxColumn.textColor
|
|
readOnly: true
|
|
selectByMouse: true
|
|
background: Rectangle {
|
|
color: "transparent"
|
|
}
|
|
padding: 0; leftPadding: 0; topPadding: 0 // With the padding at zero, we can freely set the Row spacing
|
|
}
|
|
Text {
|
|
id: balanceUnlockedCurrencySign
|
|
anchors.verticalCenter: parent.children[0].verticalCenter
|
|
text: qsTr("XMR")
|
|
font.bold: balanceUnlockedText.font.bold
|
|
font.pointSize: balanceUnlockedText.font.pointSize
|
|
color: "#404040"
|
|
visible: settingsDialog.showCurrencySign && balanceUnlockedText.visible
|
|
}
|
|
}
|
|
|
|
Row {
|
|
anchors.horizontalCenter: !balanceUnlockedText.visible ? parent.horizontalCenter: parent.children[0].horizontalCenter
|
|
spacing: 5
|
|
Text {
|
|
visible: balanceLockedText.visible
|
|
anchors.verticalCenter: parent.children[1].verticalCenter
|
|
text: qsTr("\uf023 ")
|
|
font.bold: true
|
|
font.family: FontAwesome.fontFamily
|
|
font.pixelSize: balanceLockedText.font.pointSize
|
|
color: (NeroshopComponents.Style.darkTheme) ? "#ffffff" : "#000000"
|
|
}
|
|
/*Image {
|
|
id: lockedIcon
|
|
anchors.verticalCenter: parent.children[1].verticalCenter
|
|
width: 32; height: width
|
|
source: "qrc:/assets/images/lock.png"
|
|
mipmap: true
|
|
}*/
|
|
/*ColorOverlay {
|
|
anchors.fill: lockedIcon
|
|
source: lockedIcon
|
|
color: (NeroshopComponents.Style.darkTheme) ? "#ffffff" : "#000000"
|
|
visible: lockedIcon.visible
|
|
}*/
|
|
TextField {
|
|
id: balanceLockedText
|
|
visible: (settingsDialog.balanceDisplay == 2) ? false : true
|
|
property double balance: !Wallet.opened || (Wallet.balanceLocked == Wallet.balanceUnlocked) ? 0.000000000000 : Wallet.balanceLocked - Wallet.balanceUnlocked
|
|
text: balance.toFixed(settingsDialog.balanceAmountPrecision)
|
|
font.bold: !balanceUnlockedText.visible ? true : false
|
|
font.pointSize: !balanceUnlockedText.visible ? 48 : 24
|
|
color: balanceTxColumn.textColor
|
|
readOnly: true
|
|
selectByMouse: true
|
|
background: Rectangle {
|
|
color: "transparent"
|
|
}
|
|
padding: 0; leftPadding: 0; topPadding: 0 // With the padding at zero, we can freely set the Row spacing
|
|
}
|
|
Text {
|
|
id: balanceLockedCurrencySign
|
|
anchors.verticalCenter: parent.children[1].verticalCenter
|
|
text: qsTr("XMR")
|
|
font.bold: balanceLockedText.font.bold
|
|
font.pointSize: balanceLockedText.font.pointSize
|
|
color: "#404040"
|
|
visible: settingsDialog.showCurrencySign && balanceLockedText.visible
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
NeroshopComponents.TabBar {
|
|
id: tabBar
|
|
Layout.alignment: Qt.AlignHCenter
|
|
model: ["Transactions", "Send", "Receive", "\uf013"]
|
|
color0: NeroshopComponents.Style.moneroOrangeColor
|
|
Component.onCompleted: {
|
|
buttonAt(0).checked = true
|
|
buttonAt(3).width = 50
|
|
buttonAt(3).contentItem.font.bold = true
|
|
buttonAt(3).contentItem.font.family = FontAwesome.fontFamily
|
|
}
|
|
}
|
|
|
|
StackLayout {
|
|
id: walletStack
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 300//500//Layout.fillHeight: true
|
|
currentIndex: tabBar.currentIndex
|
|
// Transactions
|
|
Item {
|
|
id: txsDisplay
|
|
// StackLayout child Items' Layout.fillWidth and Layout.fillHeight properties default to true
|
|
|
|
Flickable {
|
|
anchors.fill: parent
|
|
contentWidth: parent.width/*950*/; contentHeight: (75 * txList.count) + (txList.spacing * (txList.count - 1))
|
|
clip: true
|
|
ScrollBar.vertical: ScrollBar {
|
|
policy: ScrollBar.AsNeeded//AlwaysOff
|
|
}
|
|
ListView {
|
|
id: txList
|
|
anchors.fill: parent
|
|
//width: parent.contentWidth/*parent.width*/; height: parent.contentHeight//childrenRect.height * txRepeater.count//width: parent.contentWidth//; height: parent.height
|
|
//anchors.centerIn: parent//anchors.horizontalCenter: parent.horizontalCenter
|
|
spacing: 7
|
|
Component.onCompleted: console.log("tx count", /*txRepeater.*/count)
|
|
model: Wallet.transfers
|
|
delegate: Rectangle {
|
|
color: balanceTxColumn.baseColor
|
|
width: /*950*/parent.width; height: 75//150
|
|
radius: 5
|
|
Rectangle {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: parent.left; anchors.leftMargin: 5
|
|
width: parent.height - 10; height: width
|
|
color: "transparent"
|
|
border.color: balanceTxColumn.borderColor
|
|
|
|
Text {
|
|
anchors.centerIn: parent
|
|
text: modelData.is_incoming ? "\uf063" : "\uf062"
|
|
color: (!Wallet.opened) ? "#ffffff" : (modelData.is_incoming ? "#2cba78" : "#c32235")
|
|
font.bold: true; font.family: FontAwesome.fontFamily
|
|
font.pixelSize: 32
|
|
}
|
|
}
|
|
Column {
|
|
anchors.left: parent.children[0].right; anchors.leftMargin: 20
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 1
|
|
Text {
|
|
text: modelData.is_incoming ? qsTr("Received") : qsTr("Sent")
|
|
color: balanceTxColumn.textColor
|
|
}
|
|
Text {
|
|
text: "2024-01-01 00:00" // TODO: get actual tx date and time
|
|
color: "#777"
|
|
font.pointSize: 10
|
|
visible: false // <- hide this for now
|
|
}
|
|
}
|
|
Column {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
Text {
|
|
text: (!Wallet.opened) ? "" : qsTr("%1 %2").arg(modelData.is_incoming ? "+" : "-").arg(modelData.amount.toFixed(12))
|
|
color: (!Wallet.opened) ? "#ffffff" : (modelData.is_incoming ? "#2cba78" : "#c32235")
|
|
font.bold: true
|
|
}
|
|
Text {
|
|
text: (!Wallet.opened) ? "" : qsTr("%1 %2%3 %4").arg(modelData.is_incoming ? "+" : "-").arg(Backend.getCurrencySign(priceDisplayText.currency)).arg(CurrencyExchangeRates.getXmrPrice(priceDisplayText.currency) * modelData.amount.toFixed(12)).arg(priceDisplayText.currency.toUpperCase())
|
|
color: "#777"
|
|
font.pointSize: 10
|
|
visible: (Wallet.getWalletType() == 0 && priceDisplayText.currency != "XMR")
|
|
}
|
|
}
|
|
Button {
|
|
anchors.right: parent.right; anchors.rightMargin: 20
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: contentItem.contentWidth + 20; height: contentItem.contentHeight + 20
|
|
text: qsTr("View")
|
|
background: Rectangle {
|
|
color: "transparent"
|
|
border.color: balanceTxColumn.borderColor
|
|
radius: 3
|
|
}
|
|
contentItem: Text {
|
|
text: parent.text
|
|
color: balanceTxColumn.textColor
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
onClicked: {
|
|
let network_type = Wallet.getNetworkTypeString()
|
|
if(network_type != "mainnet") {
|
|
Qt.openUrlExternally("https://" + network_type + "." + settingsDialog.blockExplorer)
|
|
return
|
|
}
|
|
Qt.openUrlExternally("https://" + settingsDialog.blockExplorer)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Send
|
|
Item {
|
|
id: sendTab
|
|
// StackLayout child Items' Layout.fillWidth and Layout.fillHeight properties default to true
|
|
Flickable {
|
|
anchors.fill: parent
|
|
contentWidth: width; contentHeight: sendTabColumn.childrenRect.height
|
|
clip: true
|
|
ScrollBar.vertical: ScrollBar {
|
|
policy: ScrollBar.AsNeeded
|
|
}
|
|
Column {
|
|
id: sendTabColumn
|
|
anchors.fill: parent
|
|
spacing: 20 // spacing between each item inside the column
|
|
// addressField
|
|
TextField {
|
|
id: addressField
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
width: 500/*parent.width*/; height: 50
|
|
placeholderText: qsTr("Receiver address")
|
|
color: balanceTxColumn.textColor
|
|
selectByMouse: true
|
|
maximumLength: 95//200 // TODO: set to 200 when Seraphis goes live
|
|
background: Rectangle {
|
|
color: balanceTxColumn.baseColor
|
|
border.color: balanceTxColumn.borderColor
|
|
border.width: parent.activeFocus ? 2 : 1
|
|
radius: balanceTxColumn.radius
|
|
}
|
|
rightPadding: resolveButton.visible ? (15 + resolveButton.width) : leftPadding
|
|
Button {
|
|
id: resolveButton
|
|
text: qsTr("Resolve")
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: 10
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
hoverEnabled: true
|
|
visible: Wallet.isValidOpenAliasAddress(addressField.text)
|
|
////onClicked: // TODO: handle OpenAlias resolution
|
|
background: Rectangle {
|
|
color: NeroshopComponents.Style.moneroGrayColor
|
|
radius: 10
|
|
}
|
|
contentItem: Text {
|
|
text: parent.text
|
|
color: "#ffffff"
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
}
|
|
}
|
|
// amountField
|
|
TextField {
|
|
id: amountField
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
width: 500/*parent.width*/; height: 50
|
|
placeholderText: qsTr("Amount")//0.000000000000
|
|
color: balanceTxColumn.textColor
|
|
selectByMouse: true
|
|
validator: RegExpValidator{ regExp: new RegExp("^-?[0-9]+(\\.[0-9]{1," + Number(12) + "})?$") }
|
|
background: Rectangle {
|
|
color: balanceTxColumn.baseColor
|
|
border.color: balanceTxColumn.borderColor
|
|
border.width: parent.activeFocus ? 2 : 1
|
|
radius: balanceTxColumn.radius
|
|
}
|
|
rightPadding: 15 + allButton.width
|
|
Button {
|
|
id: allButton
|
|
text: qsTr("\uf534")
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: 10
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
implicitWidth: 32; implicitHeight: 24
|
|
hoverEnabled: true
|
|
onClicked: amountField.text = Wallet.getBalanceUnlocked().toFixed(12)
|
|
background: Rectangle {
|
|
color: NeroshopComponents.Style.moneroGrayColor
|
|
radius: 10//amountField.background.radius//5
|
|
}
|
|
contentItem: Text {
|
|
text: parent.text
|
|
color: "#ffffff"
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignHCenter
|
|
font.bold: true
|
|
font.family: FontAwesome.fontFamily
|
|
}
|
|
}
|
|
}
|
|
// sendButton
|
|
Button {
|
|
id: sendButton
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
width: 500; height: contentItem.contentHeight + 30
|
|
text: qsTr("Transfer")
|
|
background: Rectangle {
|
|
color: parent.hovered ? "#ff7214" : NeroshopComponents.Style.moneroOrangeColor
|
|
radius: balanceTxColumn.radius
|
|
}
|
|
contentItem: Text {
|
|
text: parent.text
|
|
color: "#ffffff"
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
onClicked: {
|
|
if(settingsDialog.requirePasswordOnWithdrawal) {
|
|
walletPasswordSendPrompt.open()
|
|
walletPasswordSendPrompt.editAt(1).forceActiveFocus()
|
|
}
|
|
else Wallet.transfer(addressField.text, amountField.text)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Enter wallet password message prompt
|
|
NeroshopComponents.MessageBox {
|
|
id: walletPasswordSendPrompt
|
|
x: mainWindow.x + (mainWindow.width - this.width) / 2
|
|
y: mainWindow.y + (mainWindow.height - this.height) / 2
|
|
title: qsTr("Send")
|
|
text: qsTr("Please enter your wallet password")
|
|
buttonModel: ["Cancel", "OK"]
|
|
editModel: 2//1
|
|
buttonRow.state: "centered"; buttonRow.width: editColumn.width
|
|
editColumn.anchors.topMargin: 0
|
|
Component.onCompleted: {
|
|
//textObject.horizontalAlignment = TextEdit.AlignLeft
|
|
|
|
const error_edit = editAt(0)
|
|
error_edit.readOnly = true
|
|
error_edit.background.color = "transparent"
|
|
const password_edit = editAt(1)
|
|
password_edit.echoMode = TextInput.Password
|
|
password_edit.inputMethodHints = Qt.ImhSensitiveData
|
|
buttonAt(0).color = NeroshopComponents.Style.moneroGrayColor
|
|
buttonAt(1).color = "#66578e"
|
|
|
|
onCloseCallback = function() {
|
|
error_edit.color = "#353637"
|
|
error_edit.text = ""
|
|
password_edit.text = ""
|
|
}
|
|
|
|
buttonAt(0).onClickedCallback = function() {
|
|
onCloseCallback()
|
|
close()
|
|
}
|
|
buttonAt(1).onClickedCallback = function() {
|
|
if(!Wallet.verifyPassword(password_edit.text)) {
|
|
error_edit.color = "#b22222"
|
|
error_edit.text = qsTr("Password is incorrect. Try again")
|
|
password_edit.text = ""
|
|
return;
|
|
}
|
|
Wallet.transfer(addressField.text, amountField.text)
|
|
// TODO: clear address and amount field if transfer was successful
|
|
/*addressField.text = ""
|
|
amountField.text = ""*/
|
|
onCloseCallback()
|
|
close()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Receive
|
|
Item {
|
|
id: receiveTab
|
|
// StackLayout child Items' Layout.fillWidth and Layout.fillHeight properties default to true
|
|
Flickable {
|
|
anchors.fill: parent
|
|
contentWidth: width; contentHeight: receiveTabColumn.childrenRect.height
|
|
clip: true
|
|
ScrollBar.vertical: ScrollBar {
|
|
policy: ScrollBar.AsNeeded
|
|
}
|
|
Column {
|
|
id: receiveTabColumn
|
|
anchors.fill: parent
|
|
spacing: 20
|
|
Row {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
spacing: 5
|
|
// Primary address
|
|
TextArea {
|
|
id: primaryAddressField
|
|
width: 750; height: 50
|
|
text: !Wallet.opened ? "" : Wallet.getPrimaryAddress()
|
|
color: balanceTxColumn.textColor
|
|
readOnly: true
|
|
selectByMouse: true
|
|
wrapMode: Text.Wrap
|
|
background: Rectangle {
|
|
color: balanceTxColumn.baseColor
|
|
border.color: balanceTxColumn.borderColor
|
|
border.width: parent.activeFocus ? 2 : 1
|
|
radius: 5//balanceTxColumn.radius
|
|
}
|
|
rightPadding: leftPadding
|
|
verticalAlignment: TextEdit.AlignVCenter // align the text within the center of TextArea item's height
|
|
horizontalAlignment: TextEdit.AlignHCenter
|
|
}
|
|
Button {
|
|
id: copyButton
|
|
width: 50; height: primaryAddressField.height
|
|
text: qsTr("Copy")
|
|
display: AbstractButton.IconOnly
|
|
icon.source: "qrc:/assets/images/copy.png"
|
|
icon.color: (NeroshopComponents.Style.darkTheme) ? "#ffffff" : "#000000"
|
|
background: Rectangle {
|
|
color: "transparent"//"#808080"
|
|
border.color: parent.hovered ? balanceTxColumn.borderColor : "transparent"
|
|
radius: 15
|
|
}
|
|
onClicked: {
|
|
primaryAddressField.selectAll()
|
|
primaryAddressField.copy()////Backend.copyTextToClipboard(primaryAddressField.text)
|
|
}
|
|
}
|
|
}
|
|
// Wallet QR
|
|
Rectangle {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
width: imageSize + 50; height: this.width
|
|
radius: 5
|
|
property real imageSize: 200
|
|
Image {
|
|
anchors.centerIn: parent
|
|
source: "image://wallet_qr/%1".arg(!Wallet.opened ? "" : Wallet.getPrimaryAddress())////"image://wallet_qr/%1".arg(Wallet.getPrimaryAddress())
|
|
sourceSize {
|
|
width: parent.imageSize
|
|
height: parent.imageSize
|
|
}
|
|
}
|
|
}
|
|
// TODO: add subaddress list
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} // root Layout
|
|
}
|