Files
pay/desktop/main.qml
T

825 lines
33 KiB
QML
Raw Permalink Normal View History

2020-05-24 13:20:03 +02:00
/*
* This file is part of the Flowee project
2022-04-05 16:37:09 +02:00
* Copyright (C) 2020-2022 Tom Zander <tom@flowee.org>
2020-05-24 13:20:03 +02:00
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2021-05-23 00:27:34 +02:00
import QtQuick 2.11
import QtQuick.Controls 2.11
import QtQuick.Layouts 1.11
2021-05-01 16:21:58 +02:00
import QtGraphicalEffects 1.0
import "widgets" as Flowee
2020-10-14 15:12:33 +02:00
import "./ControlColors.js" as ControlColors
2020-05-24 13:20:03 +02:00
ApplicationWindow {
2020-10-14 18:29:10 +02:00
id: mainWindow
2020-05-24 13:20:03 +02:00
visible: true
2021-11-02 19:29:14 +01:00
width: Pay.windowWidth === -1 ? 750 : Pay.windowWidth
height: Pay.windowHeight === -1 ? 500 : Pay.windowHeight
minimumWidth: 800
minimumHeight: 600
2020-05-24 13:20:03 +02:00
title: "Flowee Pay"
2021-11-02 19:29:14 +01:00
onWidthChanged: Pay.windowWidth = width
onHeightChanged: Pay.windowHeight = height
2020-10-14 18:29:10 +02:00
onVisibleChanged: if (visible) ControlColors.applySkin(mainWindow)
2020-10-16 18:17:56 +02:00
property bool isLoading: typeof portfolio === "undefined";
2020-06-11 17:56:06 +02:00
2021-04-20 19:30:56 +02:00
onIsLoadingChanged: {
if (!isLoading) {
2021-04-21 15:17:08 +02:00
if (!portfolio.current.isUserOwned) { // Open on receive tab if the wallet is effectively empty
2021-04-20 19:30:56 +02:00
tabbar.currentIndex = 2;
}
else {
tabbar.currentIndex = 0;
}
2021-04-21 15:17:08 +02:00
// delay loading to avoid errors due to not having a portfolio
2021-04-26 19:50:45 +02:00
// portfolio is only initialized after a second or so.
2021-04-20 19:30:56 +02:00
receivePane.source = "./ReceiveTransactionPane.qml"
2021-04-26 19:50:45 +02:00
sendTransactionPane.source = "./SendTransactionPane.qml"
2021-04-20 19:30:56 +02:00
}
}
2021-04-19 22:36:02 +02:00
property color floweeSalmon: "#ff9d94"
property color floweeBlue: "#0b1088"
property color floweeGreen: "#90e4b5"
2021-07-30 21:54:26 +02:00
Item {
2021-04-19 22:36:02 +02:00
id: mainScreen
anchors.fill: parent
2021-04-20 19:30:56 +02:00
focus: true
2021-04-19 22:36:02 +02:00
2021-07-30 21:47:15 +02:00
Rectangle {
id: header
2021-11-02 19:29:14 +01:00
color: Pay.useDarkSkin ? "#00000000" : mainWindow.floweeBlue
2021-07-30 21:47:15 +02:00
width: parent.width
height: {
var h = mainWindow.height;
if (h > 800)
return 120;
return h / 800 * 120;
}
Rectangle {
color: mainWindow.floweeBlue
2021-11-02 19:29:14 +01:00
opacity: Pay.useDarkSkin ? 1 : 0
2021-07-30 21:47:15 +02:00
width: parent.height / 5 * 4
height: width
radius: width / 2
x: 2
y: 8
Behavior on opacity { NumberAnimation { duration: 300 } }
}
Image {
2021-10-25 15:54:41 +02:00
id: appLogo
2021-07-30 21:47:15 +02:00
anchors.verticalCenter: parent.verticalCenter
x: 20
smooth: true
2021-11-21 10:59:29 +01:00
source: "qrc:/FloweePay-light.svg"
2021-07-30 21:47:15 +02:00
// ratio: 77 / 449
height: (parent.height - 20) * 7 / 10
width: height * 449 / 77
}
2021-10-25 15:54:41 +02:00
Item {
id: balanceInHeader
visible: {
if (mainWindow.isLoading)
return false;
if (portfolio.accounts.length <= 1)
return false;
// If there is not enough space here (only for quite long balances), move to the left bar
var minX = appLogo.width + totalFiatLabel.width + 50 // 50 is spacing
return x > minX;
}
width: totalBalance2.width
height: totalBalance2.height
anchors.bottom: parent.bottom
anchors.bottomMargin: tabbar.headerHeight + 5
anchors.right: parent.right
anchors.rightMargin: 10
baselineOffset: totalBalance2.baselineOffset
Flowee.BitcoinAmountLabel {
2021-10-25 15:54:41 +02:00
id: totalBalance2
value: {
if (isLoading)
return 0;
2021-11-02 19:29:14 +01:00
if (Pay.hideBalance)
2021-10-25 15:54:41 +02:00
return 88888888;
return portfolio.totalBalance
}
colorize: false
2021-10-30 19:23:43 +02:00
color: "white"
2021-10-25 15:54:41 +02:00
showFiat: false
fontPtSize: mainWindow.font.pointSize * 2
opacity: blurredTotalBalance2.visible ? 0 : 1
}
FastBlur {
id: blurredTotalBalance2
anchors.fill: parent
anchors.margins: 5
2021-11-02 19:29:14 +01:00
visible: Pay.hideBalance
2021-10-25 15:54:41 +02:00
source: totalBalance2
radius: 58
}
}
Label {
id: totalFiatLabel
anchors.baseline: balanceInHeader.baseline
anchors.right: balanceInHeader.left
anchors.rightMargin: 10
2021-10-29 18:20:42 +02:00
color: "white"
2021-10-25 15:54:41 +02:00
text: {
2021-11-02 19:29:14 +01:00
if (Pay.hideBalance && Pay.isMainChain)
2021-10-25 15:54:41 +02:00
return "-- " + Fiat.currencyName
return Fiat.formattedPrice(totalBalance.value, Fiat.price)
}
visible: balanceInHeader.visible
opacity: 0.6
}
2021-07-30 21:47:15 +02:00
}
2021-04-19 22:36:02 +02:00
Item {
id: tabbedPane
2021-04-20 15:52:11 +02:00
width: parent.width * 65 / 100
2021-04-19 22:36:02 +02:00
anchors.right: parent.right
2021-07-30 21:47:15 +02:00
anchors.top: header.bottom
anchors.topMargin: -1 * tabbar.headerHeight
anchors.bottom: parent.bottom
2021-04-19 22:36:02 +02:00
Rectangle {
anchors.fill: parent
opacity: 0.2
2021-07-30 21:54:26 +02:00
anchors.topMargin: -5
anchors.leftMargin: -5
2021-04-20 17:41:35 +02:00
radius: 5
2021-11-02 19:29:14 +01:00
color: Pay.useDarkSkin ? "black" : "white"
2021-04-19 22:36:02 +02:00
}
2021-11-02 19:38:36 +01:00
Flowee.TabBar {
2021-04-20 17:41:35 +02:00
id: tabbar
2021-04-21 16:57:14 +02:00
anchors.fill: parent
2021-04-20 17:41:35 +02:00
2021-04-21 00:11:57 +02:00
Pane {
2021-04-21 16:57:14 +02:00
property string title: qsTr("Activity")
2021-11-02 19:38:36 +01:00
property string icon: "qrc:/activityIcon-light.png"
2021-04-21 16:57:14 +02:00
anchors.fill: parent
2021-11-02 19:13:14 +01:00
Rectangle {
anchors.fill: parent
anchors.margins: -10
color: mainWindow.palette.light
radius: 10
}
2022-04-05 17:39:19 +02:00
Column {
id: activityHeader
width: parent.width
spacing: 10
2022-04-05 17:39:19 +02:00
Rectangle {
width: parent.width
height: warn.height + unarchiveButton.height + 26
2022-04-05 18:34:01 +02:00
color: Pay.useDarkSkin ? "#c1ba58" : "#f6e992"
2022-04-05 17:39:19 +02:00
visible: !isLoading && portfolio.current.isArchived
2022-04-05 18:34:01 +02:00
radius: 10
2022-04-05 17:39:19 +02:00
Text {
id: warn
y: 10
x: 10
width: parent.width - 20
horizontalAlignment: Text.AlignHCenter
color: "black"
font.bold: true
wrapMode: Text.WordWrap
text: qsTr("Archived wallets do not check for activities. Balance may be out of date.")
}
Flowee.Button {
2022-04-05 17:39:19 +02:00
id: unarchiveButton
text: qsTr("Unarchive")
anchors.right: warn.right
anchors.top: warn.bottom
anchors.topMargin: 6
onClicked: portfolio.current.isArchived = false
}
}
Rectangle {
id: needsDecryptPane
width: parent.width
height: decryptText.height + decryptPwd.height + decryptButton.height + 36
color: Pay.useDarkSkin ? "#c1ba58" : "#f6e992"
visible: !isLoading && portfolio.current.needsPinToOpen
&& !portfolio.current.isDecrypted
radius: 10
onVisibleChanged: {
decryptError.visible = false
decryptPwd.text = ""
}
Text {
id: decryptText
y: 10
x: 10
width: parent.width - 20
horizontalAlignment: Text.AlignHCenter
color: "black"
font.bold: true
wrapMode: Text.WordWrap
text: qsTr("This wallet needs a password to open.")
}
Text {
id: decryptLabel
anchors.left: decryptText.left
anchors.verticalCenter: decryptPwd.verticalCenter
color: decryptText.color
text: qsTr("Password:")
}
Flowee.TextField {
id: decryptPwd
2022-07-21 11:40:33 +02:00
focus: needsDecryptPane.visible
anchors.top: decryptText.bottom
anchors.left: decryptLabel.right
anchors.right: parent.right
anchors.margins: 6
echoMode: TextInput.Password
onAccepted: decryptButton.clicked()
}
Text {
id: decryptError
anchors.left: decryptPwd.left
anchors.verticalCenter: decryptButton.verticalCenter
color: "#830000"
font.bold: true
text: qsTr("Invalid password")
visible: false
}
Flowee.Button {
id: decryptButton
text: qsTr("Open")
anchors.right: decryptText.right
anchors.top: decryptPwd.bottom
anchors.topMargin: 6
enabled: decryptPwd.text !== ""
onClicked: {
portfolio.current.decrypt(decryptPwd.text)
if (portfolio.current.isDecrypted) {
decryptPwd.text = ""
decryptError.visible = false
} else {
decryptPwd.selectAll();
decryptError.visible = true
decryptPwd.forceActiveFocus();
}
}
}
}
2022-04-05 17:39:19 +02:00
}
2021-04-21 00:11:57 +02:00
ListView {
id: activityView
2022-07-20 20:20:23 +02:00
/*
Warning; (Qt5.15) do NOT guard the below `model` line with any isLoading stuff, it will
break showing the model properly after the default wallet gets decrypted just
after start.
*/
model: portfolio.current.transactions
2021-04-21 00:11:57 +02:00
clip: true
delegate: WalletTransaction { width: activityView.width }
2022-04-05 17:39:19 +02:00
anchors.top: activityHeader.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
ScrollBar.vertical: Flowee.ScrollThumb {
2021-11-03 11:59:58 +01:00
id: thumb
minimumSize: 20 / activityView.height
visible: size < 0.9
2021-11-03 11:59:58 +01:00
preview: Rectangle {
width: label.width + 20
height: label.height + 20
radius: 5
color: label.palette.dark
Label {
id: label
anchors.centerIn: parent
color: palette.light
text: isLoading || activityView.model === null ? "" : activityView.model.dateForItem(thumb.position);
2021-11-03 11:59:58 +01:00
}
}
2021-10-30 18:57:40 +02:00
}
2021-11-01 16:30:00 +01:00
onModelChanged: resetUnreadTimer.restart();
Timer {
id: resetUnreadTimer
2021-11-09 20:49:37 +01:00
interval: 90 * 1000
2021-11-01 16:30:00 +01:00
// remove the 'new transaction' indicator.
onTriggered: portfolio.current.transactions.lastSyncIndicator = undefined
running: activityView.enabled && activityView.visible
// copy the height so we know when the account height changes
// and we can restart our timer as a result
2022-04-06 18:18:49 +02:00
property int height: {
if (isLoading) return 0;
return portfolio.current.lastBlockSynched
}
2021-11-01 16:30:00 +01:00
onHeightChanged: restart();
}
2021-04-21 00:11:57 +02:00
}
2021-11-25 17:35:41 +01:00
Keys.forwardTo: Flowee.ListViewKeyHandler {
target: activityView
}
2021-04-20 17:41:35 +02:00
}
2021-04-26 19:50:45 +02:00
Loader {
id: sendTransactionPane
// Disable these tabs for archived accounts
enabled: !mainWindow.isLoading && !portfolio.current.isArchived
2022-06-29 14:23:54 +02:00
&& (!portfolio.current.needsPinToOpen || portfolio.current.isDecrypted)
2021-04-21 16:57:14 +02:00
anchors.fill: parent
property string title: qsTr("Send")
2021-11-02 19:38:36 +01:00
property string icon: "qrc:/sendIcon-light.png"
2021-04-21 16:57:14 +02:00
}
Loader {
id: receivePane
2022-07-06 22:06:58 +02:00
enabled: sendTransactionPane.enabled && (!portfolio.current.needSpinToOpen || portfolio.current.isDecrypted)
2021-04-21 16:57:14 +02:00
anchors.fill: parent
2021-11-02 19:38:36 +01:00
property string icon: "qrc:/receiveIcon.png"
2021-04-21 16:57:14 +02:00
property string title: qsTr("Receive")
}
2021-08-09 18:46:38 +02:00
SettingsPane {
2021-04-21 16:57:14 +02:00
anchors.fill: parent
2021-04-19 22:36:02 +02:00
}
}
Behavior on opacity { NumberAnimation { } }
visible: opacity > 0
}
Loader {
2022-04-05 16:37:09 +02:00
// This overlays the tabbed pane
id: accountOverlay
anchors.bottom: parent.bottom
anchors.left: overviewPane.right
anchors.right: parent.right
2021-07-31 14:16:28 +02:00
anchors.top: header.bottom
anchors.topMargin: -1 * tabbar.headerHeight
opacity: 0
Behavior on opacity { NumberAnimation { } }
states: [
State {
name: "showTransactions"
PropertyChanges { target: tabbedPane; opacity: 1 }
2021-11-30 22:19:40 +01:00
PropertyChanges { target: tabbar; focus: true }
PropertyChanges { target: accountOverlay;
2021-11-30 22:19:40 +01:00
opacity: 0;
source: "";
}
},
State {
name: "accountDetails"
PropertyChanges { target: accountOverlay;
2021-11-30 22:19:40 +01:00
source: "./AccountDetails.qml"
opacity: 1
focus: true
}
PropertyChanges { target: tabbedPane; opacity: 0 }
},
State {
name: "startWalletEncryption"
PropertyChanges { target: accountOverlay;
source: "./WalletEncryption.qml"
opacity: 1
focus: true
}
PropertyChanges { target: tabbedPane; opacity: 0 }
}
]
state: "showTransactions"
2021-04-19 22:36:02 +02:00
}
2021-04-20 15:52:11 +02:00
Flickable {
2022-04-05 16:37:09 +02:00
// the whole area left of the tabbed panels.
2021-04-20 15:52:11 +02:00
id: overviewPane
2021-07-30 21:47:15 +02:00
anchors.left: parent.left
anchors.right: tabbedPane.left
anchors.bottom: parent.bottom
2022-07-21 16:09:08 +02:00
anchors.bottomMargin: 10
2021-07-30 21:47:15 +02:00
anchors.top: header.bottom
2021-04-20 15:52:11 +02:00
contentWidth: leftColumn.width
contentHeight: leftColumn.height
flickableDirection: Flickable.VerticalFlick
2021-07-30 21:47:15 +02:00
clip: true
2021-04-20 15:52:11 +02:00
Column {
id: leftColumn
2021-07-30 21:54:26 +02:00
x: 10
2021-04-20 15:52:11 +02:00
width: overviewPane.width - 60
2021-10-25 15:54:41 +02:00
// the total balance is for most people not this one, but the balanceInHeader one.
// we only show this one when the header one decides it can't be seen.
Label {
id: totalBalanceLabel
visible: (mainWindow.isLoading || portfolio.accounts.length > 1) && !balanceInHeader.visible
text: qsTr("Total balance");
height: implicitHeight / 10 * 9
}
Item {
visible: totalBalanceLabel.visible
width: totalBalance.width
height: totalBalance.height
Flowee.BitcoinAmountLabel {
2021-10-25 15:54:41 +02:00
id: totalBalance
value: {
if (isLoading)
return 0;
2021-11-02 19:29:14 +01:00
if (Pay.hideBalance)
2021-10-25 15:54:41 +02:00
return 88888888;
return portfolio.totalBalance
}
colorize: false
showFiat: false
fontPtSize: mainWindow.font.pointSize * 2
opacity: blurredTotalBalance.visible ? 0 : 1
}
FastBlur {
id: blurredTotalBalance
anchors.fill: parent
anchors.margins: -5
2021-11-02 19:29:14 +01:00
visible: Pay.hideBalance
2021-10-25 15:54:41 +02:00
source: totalBalance
radius: 58
}
}
Label {
text: {
2021-11-02 19:29:14 +01:00
if (Pay.hideBalance && Pay.isMainChain)
2021-10-25 15:54:41 +02:00
return "-- " + Fiat.currencyName
return Fiat.formattedPrice(totalBalance.value, Fiat.price)
}
visible: totalBalanceLabel.visible
opacity: 0.6
}
Item { // spacer
width: 10
height: 50
}
2021-05-01 16:21:58 +02:00
Item {
height: balanceLabel.height
width: parent.width
Label {
id: balanceLabel
text: qsTr("Balance");
height: implicitHeight / 10 * 7
2021-04-19 22:36:02 +02:00
}
2021-05-01 16:21:58 +02:00
Image {
2021-10-25 16:23:32 +02:00
id: showBalanceButton
2021-05-01 16:21:58 +02:00
anchors.right: parent.right
source: {
2021-11-21 11:27:26 +01:00
var state = Pay.hideBalance ? "closed" : "open";
var skin = Pay.useDarkSkin ? "-light" : ""
return "qrc:/eye-" + state + skin + ".png";
2021-05-01 16:21:58 +02:00
}
smooth: true
opacity: 0.5
MouseArea {
anchors.fill: parent
2021-10-30 16:29:48 +02:00
cursorShape: Qt.PointingHandCursor
onClicked: {
2021-11-02 19:29:14 +01:00
Pay.hideBalance = !Pay.hideBalance;
balanceDetailsPane.showDetails = false;
}
2021-05-01 16:21:58 +02:00
}
2021-04-29 15:29:28 +02:00
}
2021-10-25 16:23:32 +02:00
Label {
id: questionMark
text: "🛈"
ToolTip.text: qsTr("Show Wallet Details")
anchors.right: showBalanceButton.left
anchors.baseline: balanceLabel.baseline
anchors.rightMargin: 10
opacity: 0.5
2022-04-06 14:50:05 +02:00
visible: !isLoading && !portfolio.current.isUserOwned
2021-10-25 16:23:32 +02:00
MouseArea {
anchors.fill: parent
onClicked: accountOverlay.state = "accountDetails";
2021-10-25 16:23:32 +02:00
}
}
2021-04-20 15:52:11 +02:00
}
2021-05-01 16:21:58 +02:00
Item {
id: balanceDetailsPane
2021-08-09 18:21:51 +02:00
property bool showDetails: false
2021-05-01 16:21:58 +02:00
width: balance.width
2021-08-09 18:21:51 +02:00
height: balance.height + (showDetails ? extraBalances.height + 20 : 0)
Flowee.BitcoinAmountLabel {
2021-05-01 16:21:58 +02:00
id: balance
opacity: blurredBalance.visible ? 0 : 1
value: {
if (isLoading)
return 0;
var account = portfolio.current;
if (account === null)
return 0;
2021-11-02 19:29:14 +01:00
if (Pay.hideBalance)
2021-05-01 16:21:58 +02:00
return 88888888;
return account.balanceConfirmed + account.balanceUnconfirmed
}
colorize: false
2021-05-08 00:03:07 +02:00
showFiat: false
2021-10-30 19:23:43 +02:00
color: mainWindow.palette.text
2021-05-01 16:21:58 +02:00
fontPtSize: {
if (leftColumn.width < 300)
return mainWindow.font.pointSize * 2
return mainWindow.font.pointSize * 3
}
}
FastBlur {
id: blurredBalance
anchors.fill: parent
anchors.margins: -5
2021-11-02 19:29:14 +01:00
visible: Pay.hideBalance
2021-05-01 16:21:58 +02:00
source: balance
radius: 58
}
2021-10-14 16:10:31 +02:00
GridLayout {
2021-08-09 18:21:51 +02:00
id: extraBalances
visible: parent.showDetails
width: parent.width - 30
anchors.top: balance.bottom
anchors.topMargin: 10
columns: 2
x: 25
property QtObject account: mainWindow.isLoading ? null : portfolio.current
2021-10-14 16:10:31 +02:00
Label {
2021-11-09 21:34:40 +01:00
text: qsTr("Main", "balance (money), non specified") + ":"
2021-10-14 16:10:31 +02:00
Layout.alignment: Qt.AlignRight
}
Flowee.BitcoinAmountLabel {
2021-10-14 16:10:31 +02:00
value: extraBalances.account == null ? 0 : extraBalances.account.balanceConfirmed
colorize: false
showFiat: false
}
2021-08-09 18:21:51 +02:00
Label {
2021-11-09 21:34:40 +01:00
text: qsTr("Unconfirmed", "balance (money)") + ":"
2021-10-14 16:10:31 +02:00
Layout.alignment: Qt.AlignRight
2021-08-09 18:21:51 +02:00
}
Flowee.BitcoinAmountLabel {
2021-08-09 18:21:51 +02:00
value: extraBalances.account == null ? 0 : extraBalances.account.balanceUnconfirmed
colorize: false
showFiat: false
}
Label {
2021-11-09 21:34:40 +01:00
text: qsTr("Immature", "balance (money)") + ":"
2021-10-14 16:10:31 +02:00
Layout.alignment: Qt.AlignRight
2021-08-09 18:21:51 +02:00
}
Flowee.BitcoinAmountLabel {
2021-08-09 18:21:51 +02:00
value: extraBalances.account == null ? 0 : extraBalances.account.balanceImmature
colorize: false
showFiat: false
}
}
MouseArea {
2022-06-29 14:23:54 +02:00
enabled: priceCover.visible === false
2021-08-09 18:21:51 +02:00
anchors.fill: parent
2021-12-01 18:15:54 +01:00
cursorShape: Qt.PointingHandCursor
onClicked: {
2021-11-02 19:29:14 +01:00
if (!Pay.hideBalance)
parent.showDetails = !parent.showDetails
}
2021-08-09 18:21:51 +02:00
}
2022-06-29 14:23:54 +02:00
Rectangle {
id: priceCover // this covers the prices while the wallet is encrypted.
color: mainWindow.palette.window
opacity: 0.8
anchors.fill: parent
anchors.topMargin: 6
visible: !mainWindow.isLoading && portfolio.current.needsPinToOpen && !portfolio.current.isDecrypted
}
2021-08-09 18:21:51 +02:00
Behavior on height { NumberAnimation {} }
2021-05-01 16:21:58 +02:00
}
2021-04-20 15:52:11 +02:00
Label {
2021-05-01 17:22:19 +02:00
text: {
2022-06-29 14:23:54 +02:00
if (mainWindow.isLoading)
return "";
if (Pay.hideBalance && Pay.isMainChain
|| (portfolio.current.needsPinToOpen && !portfolio.current.isDecrypted))
return "-- " + Fiat.currencyName;
return Fiat.formattedPrice(balance.value, Fiat.price);
2021-05-01 17:22:19 +02:00
}
opacity: 0.6
2021-04-20 15:52:11 +02:00
}
2021-06-07 23:30:21 +02:00
Item { // spacer
visible: fiatValue.visible
width: 10
height: 20
}
Label {
id: fiatValue
2021-12-01 18:01:25 +01:00
property double prevPrice: 0
2021-06-07 23:30:21 +02:00
text: qsTr("1 BCH is: %1").arg(Fiat.formattedPrice(100000000, Fiat.price))
2021-11-02 19:29:14 +01:00
visible: Pay.isMainChain
2021-06-07 23:30:21 +02:00
font.pixelSize: 18
2021-12-01 18:01:25 +01:00
Behavior on color { ColorAnimation { duration: 300 } }
onTextChanged: {
animTimer.start()
if (prevPrice > Fiat.price)
color = Pay.useDarkSkin ? "#5f1414" : "#ff3636"; // red
else
color = Pay.useDarkSkin ? "#154822" : "#4aff77"; // green
prevPrice = Fiat.price
}
Timer {
id: animTimer
interval: 305
onTriggered: fiatValue.color = fiatValue.palette.text
}
2021-06-07 23:30:21 +02:00
}
2021-04-20 15:52:11 +02:00
Item { // spacer
width: 10
2021-11-02 19:57:26 +01:00
height: totalBalanceLabel.visible ? 40 : 10
2021-04-20 15:52:11 +02:00
}
Label {
text: qsTr("Network status")
opacity: 0.6
2021-04-20 15:52:11 +02:00
}
2022-04-06 18:18:49 +02:00
Label {
2021-07-31 17:19:34 +02:00
id: syncIndicator
2022-04-06 18:18:49 +02:00
text: {
if (isLoading)
2022-06-29 14:23:54 +02:00
return "";
var account = portfolio.current;
2022-04-06 18:18:49 +02:00
if (account === null)
2022-06-29 14:23:54 +02:00
return "";
if (account.needsPinToOpen && !account.isDecrypted)
return qsTr("Offline");
return account.timeBehind;
2022-04-06 18:18:49 +02:00
}
font.italic: true
2021-04-20 15:52:11 +02:00
}
Item { // spacer
width: 10
height: 60
}
Repeater { // the portfolio listing our accounts
2021-04-20 15:52:11 +02:00
width: parent.width
model: mainWindow.isLoading ? 0 : portfolio.accounts;
delegate: AccountListItem {
2021-04-20 15:52:11 +02:00
width: leftColumn.width
account: modelData
2021-04-19 22:36:02 +02:00
}
2021-04-20 15:52:11 +02:00
}
Item { // spacer
width: 10
height: 40
}
2022-04-05 17:51:08 +02:00
Rectangle { // button 'add bitcoin cash wallet'
2021-04-20 15:52:11 +02:00
color: mainWindow.floweeGreen
radius: 10
2021-04-29 12:12:12 +02:00
width: leftColumn.width
2021-04-20 15:52:11 +02:00
height: buttonLabel.height + 30
Text {
id: buttonLabel
anchors.centerIn: parent
width: parent.width - 20
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
2021-10-21 15:30:50 +02:00
text: qsTr("Add Bitcoin Cash wallet")
2021-04-29 12:12:12 +02:00
}
MouseArea {
anchors.fill: parent
2021-10-30 16:29:48 +02:00
cursorShape: Qt.PointingHandCursor
2021-10-15 21:01:40 +02:00
onClicked: newAccountPane.source = "./NewAccountPane.qml"
2021-04-19 22:36:02 +02:00
}
2021-04-20 15:52:11 +02:00
}
Item { // spacer
width: 10
height: 40
2021-04-19 22:36:02 +02:00
}
2022-04-05 17:51:08 +02:00
Item {
visible: !isLoading && portfolio.archivedAccounts.length > 0
height: archivedLabel.height
width: leftColumn.width
Flowee.ArrowPoint {
id: showArchivedWalletsList
property bool on: false
color: Pay.useDarkSkin ? "white" : "black"
rotation: on ? 90 : 0
transformOrigin: Item.Center
Behavior on rotation { NumberAnimation {} }
}
Label {
id: archivedLabel
x: showArchivedWalletsList.width + 10
text: {
if (isLoading)
return ""
var walletCount = portfolio.archivedAccounts.length
return qsTr("Archived wallets [%1]", "Arg is wallet count", walletCount).arg(walletCount);
}
2022-04-05 17:51:08 +02:00
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: showArchivedWalletsList.on = !showArchivedWalletsList.on
}
}
2022-04-05 16:37:09 +02:00
Repeater { // the archived accounts
width: parent.width
2022-04-05 17:51:08 +02:00
model: showArchivedWalletsList.on ? portfolio.archivedAccounts : 0;
2022-04-05 16:37:09 +02:00
delegate: AccountListItem {
width: leftColumn.width
account: modelData
// archived accounts don't have access to anything but the activity tab
onClicked: tabbar.currentIndex = 0; // change to the 'activity' tab
2022-04-05 16:37:09 +02:00
}
}
2021-04-19 22:36:02 +02:00
}
2021-04-20 15:52:11 +02:00
}
Rectangle {
id: splashScreen
2021-11-02 19:13:14 +01:00
color: mainWindow.palette.window
2021-04-20 15:52:11 +02:00
anchors.fill: parent
2021-11-02 19:13:14 +01:00
Label {
2021-04-29 16:33:46 +02:00
text: qsTr("Preparing...")
2021-04-20 15:52:11 +02:00
anchors.centerIn: parent
font.pointSize: 20
2021-04-19 22:36:02 +02:00
}
2021-04-20 15:52:11 +02:00
opacity: mainWindow.isLoading ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 300 } }
2021-04-19 22:36:02 +02:00
}
2021-04-20 19:30:56 +02:00
Keys.onPressed: {
if ((event.modifiers & Qt.ControlModifier) !== 0) {
if (event.key === Qt.Key_Q) {
mainWindow.close()
2020-10-15 20:04:10 +02:00
}
}
2020-10-14 15:12:33 +02:00
}
2021-04-22 16:13:40 +02:00
// NetView (reachable from settings)
Loader {
id: netView
onLoaded: {
ControlColors.applySkin(item)
netViewHandler.target = item
}
Connections {
id: netViewHandler
function onVisibleChanged() {
if (!netView.item.visible)
netView.source = ""
}
}
}
2021-10-15 21:01:40 +02:00
// new accounts pane, corresponding to the big green button
2021-04-29 12:12:12 +02:00
Loader {
2021-10-15 21:01:40 +02:00
id: newAccountPane
anchors.fill: parent
2021-10-18 16:30:21 +02:00
onLoaded: {
tabbar.enabled = false // avoid it taking focus on tab
newAccountHandler.target = item // to unload on hide
}
2021-04-29 12:12:12 +02:00
Connections {
id: newAccountHandler
function onVisibleChanged() {
2021-10-15 21:01:40 +02:00
if (!newAccountPane.item.visible) {
newAccountPane.source = ""
2021-10-18 16:30:21 +02:00
tabbar.enabled = true // reenable
tabbar.focus = true;
2021-04-29 12:12:12 +02:00
}
}
}
}
2020-10-14 15:12:33 +02:00
}
2020-05-24 13:20:03 +02:00
}