diff --git a/contrib/android/Dockerfile b/contrib/android/Dockerfile index 5c80325be..76f7cfd16 100644 --- a/contrib/android/Dockerfile +++ b/contrib/android/Dockerfile @@ -198,7 +198,7 @@ RUN cd /opt \ && git fetch --all \ # commit: from branch accumulator/qt6-wip (note: careful with force-pushing! see #8162) \ # - && git checkout "f2741f0b7b6a4ac52fc6cb0dc9ac706e2287be02^{commit}" \ + && git checkout "eb4a3522373e0b4e2749b8a8bc965ff51355ea35^{commit}" \ && /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies -e . # build env vars diff --git a/contrib/android/make_apk.sh b/contrib/android/make_apk.sh index 88625b0a9..977148bfb 100755 --- a/contrib/android/make_apk.sh +++ b/contrib/android/make_apk.sh @@ -45,7 +45,7 @@ info "apk building phase starts." # FIXME: changing "APP_PACKAGE_NAME" seems to require a clean rebuild of ".buildozer/", # to avoid that, maybe change "APP_PACKAGE_DOMAIN" instead. # So, in particular, to build a testnet apk, simply uncomment: -export APP_PACKAGE_DOMAIN=org.electrum.testnet +#export APP_PACKAGE_DOMAIN=org.electrum.testnet if [ $CI ]; then # override log level specified in buildozer.spec to "debug": diff --git a/electrum/gui/qml/components/ScanDialog.qml b/electrum/gui/qml/components/ScanDialog.qml new file mode 100644 index 000000000..f85cd82ac --- /dev/null +++ b/electrum/gui/qml/components/ScanDialog.qml @@ -0,0 +1,52 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import "controls" + +// currently not used on android, kept for future use when qt6 camera stops crashing +ElDialog { + id: scanDialog + + property string scanData + property string error + property string hint + + signal found + + width: parent.width + height: parent.height + padding: 0 + + header: null + topPadding: 0 // dialog needs topPadding override + + function doClose() { + qrscan.stop() + Qt.callLater(doReject) + } + + ColumnLayout { + anchors.fill: parent + spacing: 0 + + QRScan { + id: qrscan + Layout.fillWidth: true + Layout.fillHeight: true + hint: scanDialog.hint + onFound: { + scanDialog.scanData = scanData + scanDialog.found() + } + } + + FlatButton { + id: button + Layout.fillWidth: true + text: qsTr('Cancel') + icon.source: '../../icons/closebutton.png' + onClicked: doReject() + } + } +} diff --git a/electrum/gui/qml/components/SendDialog.qml b/electrum/gui/qml/components/SendDialog.qml new file mode 100644 index 000000000..2e77a3737 --- /dev/null +++ b/electrum/gui/qml/components/SendDialog.qml @@ -0,0 +1,83 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material + +import org.electrum 1.0 + +import "controls" + +// currently not used on android, kept for future use when qt6 camera stops crashing +ElDialog { + id: dialog + + property InvoiceParser invoiceParser + + signal txFound(data: string) + signal channelBackupFound(data: string) + + header: null + padding: 0 + topPadding: 0 + + onAboutToHide: { + console.log('about to hide') + qrscan.stop() + } + + function restart() { + qrscan.restart() + } + + function dispatch(data) { + data = data.trim() + if (bitcoin.isRawTx(data)) { + txFound(data) + } else if (Daemon.currentWallet.isValidChannelBackup(data)) { + channelBackupFound(data) + } else { + invoiceParser.recipient = data + } + } + + // override + function doClose() { + console.log('SendDialog doClose override') // doesn't trigger when going back?? + qrscan.stop() + Qt.callLater(doReject) + } + + ColumnLayout { + anchors.fill: parent + spacing: 0 + + QRScan { + id: qrscan + Layout.fillWidth: true + Layout.fillHeight: true + + hint: qsTr('Scan an Invoice, an Address, an LNURL-pay, a PSBT or a Channel backup') + onFound: dialog.dispatch(scanData) + } + + ButtonContainer { + Layout.fillWidth: true + + FlatButton { + Layout.fillWidth: true + Layout.preferredWidth: 1 + icon.source: '../../icons/copy_bw.png' + text: qsTr('Paste') + onClicked: { + qrscan.stop() + dialog.dispatch(AppController.clipboardToText()) + } + } + } + + } + + Bitcoin { + id: bitcoin + } +} diff --git a/electrum/gui/qml/components/WalletMainView.qml b/electrum/gui/qml/components/WalletMainView.qml index d802111de..78fa867b6 100644 --- a/electrum/gui/qml/components/WalletMainView.qml +++ b/electrum/gui/qml/components/WalletMainView.qml @@ -13,6 +13,7 @@ Item { property string title: Daemon.currentWallet ? Daemon.currentWallet.name : qsTr('no wallet loaded') + property var _sendDialog property string _intentUri property string _request_amount @@ -33,6 +34,14 @@ Item { } function openSendDialog() { + // Qt based send dialog if not on android + if (!AppController.isAndroid()) { + _sendDialog = qtSendDialog.createObject(mainView, {invoiceParser: invoiceParser}) + _sendDialog.open() + return + } + + // Android based send dialog if on android var scanner = app.scanDialog.createObject(mainView, { hint: qsTr('Scan an Invoice, an Address, an LNURL-pay, a PSBT or a Channel backup'), }) @@ -58,8 +67,24 @@ Item { scanner.open() } + function closeSendDialog() { + if (!AppController.isAndroid()) { + if (_sendDialog) { + _sendDialog.doClose() + _sendDialog = null + } + } + } + function restartSendDialog() { - //openSendDialog() // note: ~infinite-loop on non-android due to directly pasting from clipboard + if (!AppController.isAndroid()) { + if (_sendDialog) { + _sendDialog.restart() + } + return + } else { + openSendDialog() + } } function showExport(data, helptext) { @@ -97,6 +122,11 @@ Item { dialog.open() } + function createRequest(lightning_only, reuse_address) { + var qamt = Config.unitsToSats(_request_amount) + Daemon.currentWallet.createRequest(qamt, _request_description, _request_expiry, lightning_only, reuse_address) + } + property QtObject menu: Menu { id: menu @@ -298,6 +328,7 @@ Item { } } onValidationSuccess: { + closeSendDialog() var dialog = invoiceDialog.createObject(app, { invoice: invoiceParser, payImmediately: invoiceParser.isLnurlPay @@ -309,6 +340,7 @@ Item { } onLnurlRetrieved: { + closeSendDialog() var dialog = lnurlPayDialog.createObject(app, { invoiceParser: invoiceParser }) @@ -432,9 +464,32 @@ Item { } } - function createRequest(lightning_only, reuse_address) { - var qamt = Config.unitsToSats(_request_amount) - Daemon.currentWallet.createRequest(qamt, _request_description, _request_expiry, lightning_only, reuse_address) + Component { + id: qtSendDialog + SendDialog { + width: parent.width + height: parent.height + + onTxFound: { + app.stack.push(Qt.resolvedUrl('TxDetails.qml'), { rawtx: data }) + close() + } + onChannelBackupFound: { + var dialog = app.messageDialog.createObject(app, { + title: qsTr('Import Channel backup?'), + yesno: true + }) + dialog.accepted.connect(function() { + Daemon.currentWallet.importChannelBackup(data) + close() + }) + dialog.rejected.connect(function() { + close() + }) + dialog.open() + } + onClosed: destroy() + } } Component { diff --git a/electrum/gui/qml/components/main.qml b/electrum/gui/qml/components/main.qml index 86a66488a..eb93ce13b 100644 --- a/electrum/gui/qml/components/main.qml +++ b/electrum/gui/qml/components/main.qml @@ -377,13 +377,19 @@ ApplicationWindow } } - property alias scanDialog: _scanDialog + property Component scanDialog // set in Component.onCompleted Component { id: _scanDialog QRScanner { //onClosed: destroy() } } + Component { + id: _qtScanDialog + ScanDialog { + onClosed: destroy() + } + } property alias channelOpenProgressDialog: _channelOpenProgressDialog ChannelOpenProgressDialog { @@ -434,6 +440,12 @@ ApplicationWindow Component.onCompleted: { coverTimer.start() + if (AppController.isAndroid()) { + app.scanDialog = _scanDialog + } else { + app.scanDialog = _qtScanDialog + } + if (!Config.autoConnectDefined) { var dialog = serverConnectWizard.createObject(app) // without completed serverConnectWizard we can't start diff --git a/electrum/gui/qml/java_classes/org/electrum/qr/SimpleScannerActivity.java b/electrum/gui/qml/java_classes/org/electrum/qr/SimpleScannerActivity.java index 61f89564d..65827c6e5 100644 --- a/electrum/gui/qml/java_classes/org/electrum/qr/SimpleScannerActivity.java +++ b/electrum/gui/qml/java_classes/org/electrum/qr/SimpleScannerActivity.java @@ -25,7 +25,7 @@ import me.dm7.barcodescanner.zxing.ZXingScannerView; import com.google.zxing.Result; import com.google.zxing.BarcodeFormat; -import org.electrum.testnet.electrum.R; // TODO +import org.electrum.electrum.res.R; // package set in build.gradle public class SimpleScannerActivity extends Activity implements ZXingScannerView.ResultHandler { private static final int MY_PERMISSIONS_CAMERA = 1002;