If the user has wallets with different passwords (non-unified pw) and enters a password on startup that fails to unlock the recently used wallet this change will automatically open any other wallet if there is another wallet that can be unlocked with this password.
844 lines
26 KiB
QML
844 lines
26 KiB
QML
import QtQuick
|
|
import QtQuick.Layouts
|
|
import QtQuick.Controls
|
|
import QtQuick.Controls.Basic
|
|
import QtQuick.Controls.Material
|
|
import QtQuick.Controls.Material.impl
|
|
import QtQuick.Window
|
|
|
|
import QtQml
|
|
import QtMultimedia
|
|
|
|
import org.electrum 1.0
|
|
|
|
import "controls"
|
|
|
|
ApplicationWindow
|
|
{
|
|
id: app
|
|
|
|
visible: false // initial value
|
|
|
|
readonly property int statusBarHeight: AppController ? AppController.getStatusBarHeight() : 0
|
|
readonly property int navigationBarHeight: AppController ? AppController.getNavigationBarHeight() : 0
|
|
|
|
// dimensions ignored on android
|
|
width: 480
|
|
height: 800
|
|
|
|
Material.theme: Material.Dark
|
|
Material.primary: Material.Indigo
|
|
Material.accent: Material.LightBlue
|
|
font.pixelSize: constants.fontSizeMedium
|
|
|
|
property QtObject constants: appconstants
|
|
Constants { id: appconstants }
|
|
|
|
property alias stack: mainStackView
|
|
property alias keyboardFreeZone: _keyboardFreeZone
|
|
property alias infobanner: _infobanner
|
|
|
|
property string pendingIntent: ""
|
|
|
|
property variant activeDialogs: []
|
|
|
|
property var _exceptionDialog
|
|
|
|
property var pluginobjects: ({})
|
|
|
|
property QtObject appMenu: Menu {
|
|
id: menu
|
|
|
|
parent: Overlay.overlay
|
|
dim: true
|
|
modal: true
|
|
Overlay.modal: Rectangle {
|
|
color: "#44000000"
|
|
}
|
|
|
|
property int implicitChildrenWidth: 64
|
|
width: implicitChildrenWidth + 60 + constants.paddingLarge
|
|
|
|
MenuItem {
|
|
icon.color: action.enabled ? 'transparent' : Material.iconDisabledColor
|
|
icon.source: '../../icons/network.png'
|
|
action: Action {
|
|
text: qsTr('Network')
|
|
onTriggered: menu.openPage(Qt.resolvedUrl('NetworkOverview.qml'))
|
|
enabled: stack.currentItem.objectName != 'NetworkOverview'
|
|
}
|
|
}
|
|
|
|
MenuItem {
|
|
icon.color: action.enabled ? 'transparent' : Material.iconDisabledColor
|
|
icon.source: '../../icons/preferences.png'
|
|
action: Action {
|
|
text: qsTr('Preferences')
|
|
onTriggered: menu.openPage(Qt.resolvedUrl('Preferences.qml'))
|
|
enabled: stack.currentItem.objectName != 'Properties'
|
|
}
|
|
}
|
|
|
|
MenuItem {
|
|
icon.color: action.enabled ? 'transparent' : Material.iconDisabledColor
|
|
icon.source: '../../icons/electrum.png'
|
|
action: Action {
|
|
text: qsTr('About');
|
|
onTriggered: menu.openPage(Qt.resolvedUrl('About.qml'))
|
|
enabled: stack.currentItem.objectName != 'About'
|
|
}
|
|
}
|
|
|
|
function openPage(url) {
|
|
stack.pushOnRoot(url)
|
|
currentIndex = -1
|
|
}
|
|
|
|
// determine widest element and store in implicitChildrenWidth
|
|
function updateImplicitWidth() {
|
|
for (let i = 0; i < menu.count; i++) {
|
|
var item = menu.itemAt(i)
|
|
var txt = item.text
|
|
var txtwidth = fontMetrics.advanceWidth(txt)
|
|
if (txtwidth > menu.implicitChildrenWidth) {
|
|
menu.implicitChildrenWidth = txtwidth
|
|
}
|
|
}
|
|
}
|
|
|
|
FontMetrics {
|
|
id: fontMetrics
|
|
font: menu.font
|
|
}
|
|
|
|
Component.onCompleted: updateImplicitWidth()
|
|
}
|
|
|
|
function openAppMenu() {
|
|
appMenu.open()
|
|
appMenu.x = app.width - appMenu.width
|
|
appMenu.y = toolbar.height
|
|
}
|
|
|
|
header: ToolBar {
|
|
id: toolbar
|
|
|
|
// Add top margin for status bar on Android when using edge-to-edge
|
|
topPadding: app.statusBarHeight
|
|
|
|
background: Rectangle {
|
|
implicitHeight: 48
|
|
color: Material.dialogColor
|
|
|
|
layer.enabled: true
|
|
layer.effect: ElevationEffect {
|
|
elevation: 4
|
|
fullWidth: true
|
|
}
|
|
}
|
|
|
|
ColumnLayout {
|
|
spacing: 0
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
height: toolbar.availableHeight
|
|
|
|
RowLayout {
|
|
id: toolbarTopLayout
|
|
|
|
Layout.fillWidth: true
|
|
Layout.rightMargin: constants.paddingMedium
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: Math.max(implicitHeight, toolbarTopLayout.height)
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
enabled: Daemon.currentWallet &&
|
|
(!stack.currentItem || !stack.currentItem.title || stack.currentItem.title == Daemon.currentWallet.name)
|
|
onClicked: {
|
|
stack.getRoot().menu.open() // open wallet-menu
|
|
stack.getRoot().menu.y = toolbar.height
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
width: parent.width
|
|
|
|
Item {
|
|
Layout.preferredWidth: constants.paddingXLarge
|
|
Layout.preferredHeight: 1
|
|
}
|
|
|
|
Image {
|
|
Layout.preferredWidth: constants.iconSizeSmall
|
|
Layout.preferredHeight: constants.iconSizeSmall
|
|
visible: Daemon.currentWallet &&
|
|
(!stack.currentItem || !stack.currentItem.title || stack.currentItem.title == Daemon.currentWallet.name)
|
|
source: '../../icons/wallet.png'
|
|
}
|
|
|
|
Label {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: Math.max(implicitHeight, toolbarTopLayout.height)
|
|
text: stack.currentItem && stack.currentItem.title
|
|
? stack.currentItem.title
|
|
: Daemon.currentWallet.name
|
|
elide: Label.ElideRight
|
|
verticalAlignment: Qt.AlignVCenter
|
|
font.pixelSize: constants.fontSizeMedium
|
|
font.bold: true
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
implicitHeight: 48
|
|
implicitWidth: statusIconsLayout.width
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: openAppMenu() // open global-app-menu
|
|
}
|
|
|
|
RowLayout {
|
|
id: statusIconsLayout
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
Item {
|
|
Layout.preferredWidth: constants.paddingLarge
|
|
Layout.preferredHeight: 1
|
|
}
|
|
|
|
Item {
|
|
visible: Network.isTestNet
|
|
width: column.width
|
|
height: column.height
|
|
|
|
ColumnLayout {
|
|
id: column
|
|
spacing: 0
|
|
Image {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
Layout.preferredWidth: constants.iconSizeSmall
|
|
Layout.preferredHeight: constants.iconSizeSmall
|
|
source: "../../icons/info.png"
|
|
}
|
|
|
|
Label {
|
|
id: networkNameLabel
|
|
text: Network.networkName
|
|
color: Material.accentColor
|
|
font.pixelSize: constants.fontSizeXSmall
|
|
}
|
|
}
|
|
}
|
|
|
|
LightningNetworkStatusIndicator {
|
|
id: lnnsi
|
|
}
|
|
OnchainNetworkStatusIndicator { }
|
|
}
|
|
}
|
|
}
|
|
|
|
// hack to force relayout of toolbar
|
|
// since qt6 LightningNetworkStatusIndicator.visible doesn't trigger relayout(?)
|
|
Item {
|
|
Layout.preferredHeight: 1
|
|
Layout.topMargin: -1
|
|
Layout.preferredWidth: lnnsi.visible
|
|
? 1
|
|
: 2
|
|
}
|
|
}
|
|
}
|
|
|
|
ColumnLayout {
|
|
width: parent.width
|
|
height: _keyboardFreeZone.height - header.height
|
|
spacing: 0
|
|
|
|
InfoBanner {
|
|
id: _infobanner
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
StackView {
|
|
id: mainStackView
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
|
|
initialItem: Component {
|
|
Wallets {}
|
|
}
|
|
|
|
function getRoot() {
|
|
return mainStackView.get(0)
|
|
}
|
|
function pushOnRoot(item) {
|
|
if (mainStackView.depth > 1) {
|
|
mainStackView.replace(mainStackView.get(1), item)
|
|
} else {
|
|
mainStackView.push(item)
|
|
}
|
|
}
|
|
function replaceRoot(item_url) {
|
|
mainStackView.clear()
|
|
mainStackView.push(Qt.resolvedUrl(item_url))
|
|
}
|
|
}
|
|
|
|
// Add bottom padding for navigation bar on Android when UI is edge-to-edge
|
|
Item {
|
|
visible: app.navigationBarHeight > 0
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: app.navigationBarHeight
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: coverTimer
|
|
interval: 10
|
|
onTriggered: {
|
|
app.visible = true
|
|
cover.opacity = 0
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
id: cover
|
|
parent: Overlay.overlay
|
|
anchors.fill: parent
|
|
|
|
z: 1000
|
|
color: 'black'
|
|
|
|
Behavior on opacity {
|
|
enabled: AppController ? AppController.isAndroid() : false
|
|
NumberAnimation {
|
|
duration: 1000
|
|
easing.type: Easing.OutQuad;
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: _keyboardFreeZone
|
|
// Item as first child in Overlay that adjusts its size to the available
|
|
// screen space minus the virtual keyboard (e.g. to center dialogs in)
|
|
// see also ElDialog.resizeWithKeyboard property
|
|
parent: Overlay.overlay
|
|
width: parent.width
|
|
height: parent.height
|
|
|
|
states: [
|
|
State {
|
|
name: 'visible'
|
|
when: Qt.inputMethod.keyboardRectangle.y
|
|
PropertyChanges {
|
|
target: _keyboardFreeZone
|
|
height: _keyboardFreeZone.parent.height - (Screen.desktopAvailableHeight - (Qt.inputMethod.keyboardRectangle.y/Screen.devicePixelRatio))
|
|
}
|
|
}
|
|
]
|
|
|
|
transitions: [
|
|
Transition {
|
|
from: ''
|
|
to: 'visible'
|
|
NumberAnimation {
|
|
properties: 'height'
|
|
duration: 100
|
|
easing.type: Easing.OutQuad
|
|
}
|
|
},
|
|
Transition {
|
|
from: 'visible'
|
|
to: ''
|
|
SequentialAnimation {
|
|
PauseAnimation {
|
|
duration: 200
|
|
}
|
|
NumberAnimation {
|
|
properties: 'height'
|
|
duration: 50
|
|
easing.type: Easing.OutQuad
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
property alias newWalletWizard: _newWalletWizard
|
|
Component {
|
|
id: _newWalletWizard
|
|
NewWalletWizard {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias termsOfUseWizard: _termsOfUseWizard
|
|
Component {
|
|
id: _termsOfUseWizard
|
|
TermsOfUseWizard {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias serverConnectWizard: _serverConnectWizard
|
|
Component {
|
|
id: _serverConnectWizard
|
|
ServerConnectWizard {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias messageDialog: _messageDialog
|
|
Component {
|
|
id: _messageDialog
|
|
MessageDialog {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias helpDialog: _helpDialog
|
|
Component {
|
|
id: _helpDialog
|
|
HelpDialog {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias passwordDialog: _passwordDialog
|
|
Component {
|
|
id: _passwordDialog
|
|
PasswordDialog {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias pinDialog: _pinDialog
|
|
Component {
|
|
id: _pinDialog
|
|
Pin {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias genericShareDialog: _genericShareDialog
|
|
Component {
|
|
id: _genericShareDialog
|
|
GenericShareDialog {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias openWalletDialog: _openWalletDialog
|
|
Component {
|
|
id: _openWalletDialog
|
|
OpenWalletDialog {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias loadingWalletDialog: _loadingWalletDialog
|
|
Component {
|
|
id: _loadingWalletDialog
|
|
LoadingWalletDialog {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property Component scanDialog // set in Component.onCompleted
|
|
Component {
|
|
id: _scanDialog
|
|
QRScanner {
|
|
onFinished: destroy()
|
|
}
|
|
}
|
|
Component {
|
|
id: _qtScanDialog
|
|
ScanDialog {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: crashDialog
|
|
ExceptionDialog {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias channelOpenProgressDialog: _channelOpenProgressDialog
|
|
ChannelOpenProgressDialog {
|
|
id: _channelOpenProgressDialog
|
|
}
|
|
|
|
property alias signVerifyMessageDialog: _signVerifyMessageDialog
|
|
Component {
|
|
id: _signVerifyMessageDialog
|
|
SignVerifyMessageDialog {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
property alias nostrSwapServersDialog: _nostrSwapServersDialog
|
|
Component {
|
|
id: _nostrSwapServersDialog
|
|
NostrSwapServersDialog {
|
|
onClosed: destroy()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: swapDialog
|
|
SwapDialog {
|
|
id: _swapdialog
|
|
onClosed: destroy()
|
|
swaphelper: SwapHelper {
|
|
id: _swaphelper
|
|
wallet: Daemon.currentWallet
|
|
onAuthRequired: (method, authMessage) => {
|
|
app.handleAuthRequired(_swaphelper, method, authMessage)
|
|
}
|
|
onError: (message) => {
|
|
var dialog = app.messageDialog.createObject(app, {
|
|
title: qsTr('Error'),
|
|
iconSource: Qt.resolvedUrl('../../icons/warning.png'),
|
|
text: message
|
|
})
|
|
dialog.open()
|
|
}
|
|
onUndefinedNPub: {
|
|
var dialog = app.nostrSwapServersDialog.createObject(app, {
|
|
swaphelper: _swaphelper,
|
|
selectedPubkey: Config.swapServerNPub
|
|
})
|
|
dialog.accepted.connect(function() {
|
|
Config.swapServerNPub = dialog.selectedPubkey
|
|
_swaphelper.setReadyState()
|
|
})
|
|
dialog.rejected.connect(function() {
|
|
_swaphelper.npubSelectionCancelled()
|
|
})
|
|
dialog.open()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
NotificationPopup {
|
|
id: notificationPopup
|
|
width: parent.width
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
coverTimer.start()
|
|
|
|
if (AppController.isAndroid()) {
|
|
app.scanDialog = _scanDialog
|
|
} else {
|
|
app.scanDialog = _qtScanDialog
|
|
}
|
|
|
|
function continueWithServerConnection() {
|
|
if (!Network.autoConnectDefined) {
|
|
var dialog = serverConnectWizard.createObject(app)
|
|
// without completed serverConnectWizard we can't start
|
|
dialog.rejected.connect(function() {
|
|
app.visible = false
|
|
AppController.wantClose = true
|
|
Qt.callLater(Qt.quit)
|
|
})
|
|
dialog.accepted.connect(function() {
|
|
Daemon.startNetwork()
|
|
var newww = app.newWalletWizard.createObject(app)
|
|
newww.walletCreated.connect(function() {
|
|
Daemon.availableWallets.reload()
|
|
// and load the new wallet
|
|
Daemon.loadWallet(newww.path, newww.wizard_data['password'])
|
|
})
|
|
newww.open()
|
|
})
|
|
dialog.open()
|
|
} else {
|
|
Daemon.startNetwork()
|
|
if (Daemon.availableWallets.rowCount() > 0) {
|
|
Daemon.loadWallet()
|
|
} else {
|
|
var newww = app.newWalletWizard.createObject(app)
|
|
newww.walletCreated.connect(function() {
|
|
Daemon.availableWallets.reload()
|
|
// and load the new wallet
|
|
Daemon.loadWallet(newww.path, newww.wizard_data['password'])
|
|
})
|
|
newww.open()
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!Config.termsOfUseAccepted) {
|
|
var dialog = termsOfUseWizard.createObject(app)
|
|
|
|
dialog.rejected.connect(function() {
|
|
app.visible = false
|
|
AppController.wantClose = true
|
|
Qt.callLater(Qt.quit)
|
|
})
|
|
dialog.accepted.connect(function() {
|
|
Config.termsOfUseAccepted = true
|
|
continueWithServerConnection()
|
|
})
|
|
dialog.open()
|
|
} else {
|
|
continueWithServerConnection()
|
|
}
|
|
}
|
|
|
|
onClosing: (close) => {
|
|
if (AppController.wantClose) {
|
|
// destroy most GUI components so that we don't dump so many null reference warnings on exit
|
|
app.header.visible = false
|
|
mainStackView.clear()
|
|
return
|
|
}
|
|
if (activeDialogs.length > 0) {
|
|
var activeDialog = activeDialogs[activeDialogs.length - 1]
|
|
if (activeDialog.allowClose) {
|
|
console.log('main: dialog.doClose')
|
|
activeDialog.doClose()
|
|
} else {
|
|
console.log('dialog disallowed close')
|
|
}
|
|
close.accepted = false
|
|
return
|
|
}
|
|
if (stack.depth > 1) {
|
|
close.accepted = false
|
|
stack.pop()
|
|
} else {
|
|
var dialog = app.messageDialog.createObject(app, {
|
|
title: qsTr('Close Electrum?'),
|
|
yesno: true
|
|
})
|
|
dialog.accepted.connect(function() {
|
|
AppController.wantClose = true
|
|
app.close()
|
|
})
|
|
dialog.open()
|
|
close.accepted = false
|
|
}
|
|
}
|
|
|
|
property var _opendialog: undefined
|
|
property var _opendialog_startup: true
|
|
|
|
function showOpenWalletDialog(name, path) {
|
|
if (_opendialog == undefined) {
|
|
_opendialog = openWalletDialog.createObject(app, {
|
|
name: name,
|
|
path: path,
|
|
isStartup: _opendialog_startup,
|
|
})
|
|
_opendialog.closed.connect(function() {
|
|
_opendialog = undefined
|
|
_opendialog_startup = false
|
|
})
|
|
_opendialog.open()
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: Daemon
|
|
function onWalletRequiresPassword(name, path) {
|
|
console.log('wallet requires password')
|
|
showOpenWalletDialog(name, path)
|
|
}
|
|
function onWalletOpenError(error) {
|
|
console.log('wallet open error')
|
|
var dialog = app.messageDialog.createObject(app, {
|
|
title: qsTr('Error'),
|
|
iconSource: Qt.resolvedUrl('../../icons/warning.png'),
|
|
text: error
|
|
})
|
|
dialog.open()
|
|
}
|
|
function onAuthRequired(method, authMessage) {
|
|
handleAuthRequired(Daemon, method, authMessage)
|
|
}
|
|
function onLoadingChanged() {
|
|
if (!Daemon.loading)
|
|
return
|
|
console.log('wallet loading')
|
|
var dialog = loadingWalletDialog.createObject(app, { allowClose: false } )
|
|
dialog.open()
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: AppController
|
|
function onUserNotify(wallet_name, message) {
|
|
notificationPopup.show(wallet_name, message)
|
|
}
|
|
function onShowException(crash_data) {
|
|
if (app._exceptionDialog)
|
|
return
|
|
app._exceptionDialog = crashDialog.createObject(app, {
|
|
crashData: crash_data
|
|
})
|
|
app._exceptionDialog.onClosed.connect(function() {
|
|
app._exceptionDialog = null
|
|
})
|
|
app._exceptionDialog.open()
|
|
}
|
|
function onPluginLoaded(name) {
|
|
console.log('plugin ' + name + ' loaded')
|
|
var loader = AppController.plugin(name).loader
|
|
if (loader == undefined)
|
|
return
|
|
var url = Qt.resolvedUrl('../../../plugins/' + name + '/qml/' + loader)
|
|
var comp = Qt.createComponent(url)
|
|
if (comp.status == Component.Error) {
|
|
console.log('Could not find/parse PluginLoader for plugin ' + name)
|
|
console.log(comp.errorString())
|
|
return
|
|
}
|
|
var obj = comp.createObject(app)
|
|
if (obj != null)
|
|
app.pluginobjects[name] = obj
|
|
}
|
|
function onUriReceived(uri) {
|
|
console.log('uri received (main): ' + uri)
|
|
app.pendingIntent = uri
|
|
}
|
|
}
|
|
|
|
function pluginsComponentsByName(comp_name) {
|
|
// return named QML components from plugins
|
|
var plugins = AppController.plugins
|
|
var result = []
|
|
for (var i=0; i < plugins.length; i++) {
|
|
if (!plugins[i].enabled)
|
|
continue
|
|
var pluginobject = app.pluginobjects[plugins[i].name]
|
|
if (!pluginobject)
|
|
continue
|
|
if (!(comp_name in pluginobject))
|
|
continue
|
|
var comp = pluginobject[comp_name]
|
|
if (!comp)
|
|
continue
|
|
|
|
result.push(comp)
|
|
}
|
|
return result
|
|
}
|
|
|
|
Connections {
|
|
target: Daemon.currentWallet
|
|
function onAuthRequired(method, authMessage) {
|
|
handleAuthRequired(Daemon.currentWallet, method, authMessage)
|
|
}
|
|
// TODO: add to notification queue instead of barging through
|
|
function onPaymentSucceeded(key) {
|
|
notificationPopup.show(Daemon.currentWallet.name, qsTr('Payment succeeded'))
|
|
}
|
|
function onPaymentFailed(key, reason) {
|
|
notificationPopup.show(Daemon.currentWallet.name, qsTr('Payment failed') + ': ' + reason)
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: Config
|
|
function onAuthRequired(method, authMessage) {
|
|
handleAuthRequired(Config, method, authMessage)
|
|
}
|
|
}
|
|
|
|
function handleAuthRequired(qtobject, method, authMessage) {
|
|
console.log('auth using method ' + method)
|
|
|
|
if (method == 'wallet_else_pin') {
|
|
// if there is a loaded wallet and all wallets use the same password, use that
|
|
// else delegate to pin auth
|
|
if (Daemon.currentWallet && Daemon.singlePasswordEnabled) {
|
|
method = 'wallet'
|
|
} else {
|
|
method = 'pin'
|
|
}
|
|
}
|
|
|
|
if (method == 'wallet') {
|
|
if (Daemon.currentWallet.verifyPassword('')) {
|
|
// wallet has no password
|
|
qtobject.authProceed()
|
|
} else {
|
|
var dialog = app.passwordDialog.createObject(app, {'title': qsTr('Enter current password')})
|
|
dialog.accepted.connect(function() {
|
|
if (Daemon.currentWallet.verifyPassword(dialog.password)) {
|
|
qtobject.authProceed()
|
|
} else {
|
|
qtobject.authCancel()
|
|
}
|
|
})
|
|
dialog.rejected.connect(function() {
|
|
qtobject.authCancel()
|
|
})
|
|
dialog.open()
|
|
}
|
|
} else if (method == 'pin') {
|
|
if (Config.pinCode == '') {
|
|
// no PIN configured
|
|
handleAuthConfirmationOnly(qtobject, authMessage)
|
|
} else {
|
|
var dialog = app.pinDialog.createObject(app, {
|
|
mode: 'check',
|
|
pincode: Config.pinCode,
|
|
authMessage: authMessage
|
|
})
|
|
dialog.accepted.connect(function() {
|
|
qtobject.authProceed()
|
|
dialog.close()
|
|
})
|
|
dialog.rejected.connect(function() {
|
|
qtobject.authCancel()
|
|
})
|
|
dialog.open()
|
|
}
|
|
} else {
|
|
console.log('unknown auth method ' + method)
|
|
qtobject.authCancel()
|
|
}
|
|
}
|
|
|
|
function handleAuthConfirmationOnly(qtobject, authMessage) {
|
|
if (!authMessage) {
|
|
qtobject.authProceed()
|
|
return
|
|
}
|
|
var dialog = app.messageDialog.createObject(app, {
|
|
title: authMessage,
|
|
yesno: true
|
|
})
|
|
dialog.accepted.connect(function() {
|
|
qtobject.authProceed()
|
|
})
|
|
dialog.rejected.connect(function() {
|
|
qtobject.authCancel()
|
|
})
|
|
dialog.open()
|
|
}
|
|
|
|
function startSwap() {
|
|
var swapdialog = swapDialog.createObject(app)
|
|
swapdialog.open()
|
|
}
|
|
|
|
property var _lastActive: 0 // record time of last activity
|
|
property bool _lockDialogShown: false
|
|
|
|
}
|