diff --git a/electrum/gui/qml/components/Receive.qml b/electrum/gui/qml/components/Receive.qml index a082a4ffc..20c74792b 100644 --- a/electrum/gui/qml/components/Receive.qml +++ b/electrum/gui/qml/components/Receive.qml @@ -129,6 +129,7 @@ Pane { Layout.columnSpan: 4 Layout.alignment: Qt.AlignHCenter text: qsTr('Create Request') + icon.source: '../../icons/qrcode.png' onClicked: { createRequest() } @@ -202,52 +203,90 @@ Pane { rightMargin: constants.paddingSmall } - columns: 5 + columns: 2 Rectangle { - Layout.columnSpan: 5 + Layout.columnSpan: 2 Layout.fillWidth: true Layout.preferredHeight: constants.paddingTiny color: 'transparent' } + Image { Layout.rowSpan: 2 Layout.preferredWidth: constants.iconSizeLarge Layout.preferredHeight: constants.iconSizeLarge source: model.type == 0 ? "../../icons/bitcoin.png" : "../../icons/lightning.png" } - Label { - Layout.fillWidth: true - Layout.columnSpan: 2 - text: model.message - elide: Text.ElideRight - font.pixelSize: constants.fontSizeLarge - } - Label { - text: qsTr('Amount: ') - } - Label { - id: amount - text: Config.formatSats(model.amount, true) - font.family: FixedFont + RowLayout { + Layout.fillWidth: true + Label { + Layout.fillWidth: true + text: model.message ? model.message : model.address + elide: Text.ElideRight + wrapMode: Text.Wrap + maximumLineCount: 2 + font.pixelSize: model.message ? constants.fontSizeMedium : constants.fontSizeSmall + } + + Label { + id: amount + text: model.amount == 0 ? '' : Config.formatSats(model.amount) + font.pixelSize: constants.fontSizeMedium + font.family: FixedFont + } + + Label { + text: model.amount == 0 ? '' : Config.baseUnit + font.pixelSize: constants.fontSizeMedium + color: Material.accentColor + } } - Label { - text: qsTr('Timestamp: ') - } - Label { - text: model.date + RowLayout { + Layout.fillWidth: true + Label { + text: model.status_str + color: Material.accentColor + } + Item { + Layout.fillWidth: true + Layout.preferredHeight: status_icon.height + Image { + id: status_icon + source: model.status == 0 + ? '../../icons/unpaid.png' + : model.status == 1 + ? '../../icons/expired.png' + : model.status == 3 + ? '../../icons/confirmed.png' + : model.status == 7 + ? '../../icons/unconfirmed.png' + : '' + width: constants.iconSizeSmall + height: constants.iconSizeSmall + } + } + Label { + id: fiatValue + visible: Daemon.fx.enabled + Layout.alignment: Qt.AlignRight + text: model.amount == 0 ? '' : Daemon.fx.fiatValue(model.amount, false) + font.family: FixedFont + font.pixelSize: constants.fontSizeSmall + } + Label { + visible: Daemon.fx.enabled + Layout.alignment: Qt.AlignRight + text: model.amount == 0 ? '' : Daemon.fx.fiatCurrency + font.pixelSize: constants.fontSizeSmall + color: Material.accentColor + } } - Label { - text: qsTr('Status: ') - } - Label { - text: model.status - } Rectangle { - Layout.columnSpan: 5 + Layout.columnSpan: 2 Layout.fillWidth: true Layout.preferredHeight: constants.paddingTiny color: 'transparent' @@ -257,10 +296,16 @@ Pane { Connections { target: Config function onBaseUnitChanged() { - amount.text = Config.formatSats(model.amount, true) + amount.text = model.amount == 0 ? '' : Config.formatSats(model.amount) } function onThousandsSeparatorChanged() { - amount.text = Config.formatSats(model.amount, true) + amount.text = model.amount == 0 ? '' : Config.formatSats(model.amount) + } + } + Connections { + target: Daemon.fx + function onQuotesUpdated() { + fiatValue.text = model.amount == 0 ? '' : Daemon.fx.fiatValue(model.amount, false) } } @@ -269,11 +314,14 @@ Pane { } remove: Transition { - NumberAnimation { properties: 'scale'; to: 0; duration: 400 } + NumberAnimation { properties: 'scale'; to: 0.75; duration: 300 } NumberAnimation { properties: 'opacity'; to: 0; duration: 300 } } removeDisplaced: Transition { - SpringAnimation { properties: 'y'; duration: 100; spring: 5; damping: 0.5; mass: 2 } + SequentialAnimation { + PauseAnimation { duration: 200 } + SpringAnimation { properties: 'y'; duration: 100; spring: 5; damping: 0.5; mass: 2 } + } } ScrollIndicator.vertical: ScrollIndicator { } @@ -330,8 +378,7 @@ Pane { Connections { target: Daemon.fx function onQuotesUpdated() { - var a = Config.unitsToSats(amount.text) - amountFiat.text = Daemon.fx.fiatValue(a) + amountFiat.text = Daemon.fx.fiatValue(Config.unitsToSats(amount.text)) } } diff --git a/electrum/gui/qml/components/RequestDialog.qml b/electrum/gui/qml/components/RequestDialog.qml index 29586ed6c..45f9b06dc 100644 --- a/electrum/gui/qml/components/RequestDialog.qml +++ b/electrum/gui/qml/components/RequestDialog.qml @@ -11,6 +11,8 @@ Dialog { property var modelItem + property string _bip21uri + parent: Overlay.overlay modal: true standardButtons: Dialog.Ok @@ -46,18 +48,18 @@ Dialog { id: rootLayout width: parent.width rowSpacing: constants.paddingMedium - columns: 4 + columns: 5 Rectangle { height: 1 Layout.fillWidth: true - Layout.columnSpan: 4 + Layout.columnSpan: 5 color: Material.accentColor } Image { id: qr - Layout.columnSpan: 4 + Layout.columnSpan: 5 Layout.alignment: Qt.AlignHCenter Layout.topMargin: constants.paddingSmall Layout.bottomMargin: constants.paddingSmall @@ -71,6 +73,7 @@ Dialog { height: size Image { + source: '../../icons/electrum.png' x: 1 y: 1 @@ -84,12 +87,12 @@ Dialog { Rectangle { height: 1 Layout.fillWidth: true - Layout.columnSpan: 4 + Layout.columnSpan: 5 color: Material.accentColor } RowLayout { - Layout.columnSpan: 4 + Layout.columnSpan: 5 Layout.alignment: Qt.AlignHCenter Button { icon.source: '../../icons/delete.png' @@ -103,7 +106,9 @@ Dialog { icon.source: '../../icons/copy_bw.png' icon.color: 'transparent' text: 'Copy' - enabled: false + onClicked: { + AppController.textToClipboard(_bip21uri) + } } Button { icon.source: '../../icons/share.png' @@ -117,9 +122,9 @@ Dialog { } Label { visible: modelItem.message != '' - Layout.columnSpan: 3 + Layout.columnSpan: 4 Layout.fillWidth: true - wrapMode: Text.WordWrap + wrapMode: Text.Wrap text: modelItem.message font.pixelSize: constants.fontSizeLarge } @@ -136,19 +141,29 @@ Dialog { } Label { visible: modelItem.amount > 0 - Layout.fillWidth: true - Layout.columnSpan: 2 text: Config.baseUnit color: Material.accentColor font.pixelSize: constants.fontSizeLarge } + Label { + id: fiatValue + visible: modelItem.amount > 0 + Layout.fillWidth: true + Layout.columnSpan: 2 + text: Daemon.fx.enabled + ? '(' + Daemon.fx.fiatValue(modelItem.amount, false) + ' ' + Daemon.fx.fiatCurrency + ')' + : '' + font.pixelSize: constants.fontSizeMedium + wrapMode: Text.Wrap + } + Label { text: qsTr('Address') } Label { Layout.fillWidth: true - Layout.columnSpan: 2 + Layout.columnSpan: 3 font.family: FixedFont font.pixelSize: constants.fontSizeLarge wrapMode: Text.WrapAnywhere @@ -165,10 +180,10 @@ Dialog { text: qsTr('Status') } Label { - Layout.columnSpan: 3 + Layout.columnSpan: 4 Layout.fillWidth: true font.pixelSize: constants.fontSizeLarge - text: modelItem.status + text: modelItem.status_str } } @@ -184,8 +199,8 @@ Dialog { } Component.onCompleted: { - var bip21uri = bitcoin.create_uri(modelItem.address, modelItem.amount, modelItem.message, modelItem.timestamp, modelItem.exp) - qr.source = 'image://qrgen/' + bip21uri + _bip21uri = bitcoin.create_uri(modelItem.address, modelItem.amount, modelItem.message, modelItem.timestamp, modelItem.exp) + qr.source = 'image://qrgen/' + _bip21uri } Bitcoin { diff --git a/electrum/gui/qml/qerequestlistmodel.py b/electrum/gui/qml/qerequestlistmodel.py index 25ec63ca6..f6b129120 100644 --- a/electrum/gui/qml/qerequestlistmodel.py +++ b/electrum/gui/qml/qerequestlistmodel.py @@ -14,7 +14,7 @@ class QERequestListModel(QAbstractListModel): _logger = get_logger(__name__) # define listmodel rolemap - _ROLE_NAMES=('key','type','timestamp','date','message','amount','status','address','exp') + _ROLE_NAMES=('key','type','timestamp','date','message','amount','status','status_str','address','exp') _ROLE_KEYS = range(Qt.UserRole + 1, Qt.UserRole + 1 + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -44,7 +44,8 @@ class QERequestListModel(QAbstractListModel): item = {} key = self.wallet.get_key_for_receive_request(req) # (verified) address for onchain, rhash for LN status = self.wallet.get_request_status(key) - item['status'] = req.get_status_str(status) + item['status'] = status + item['status_str'] = req.get_status_str(status) item['type'] = req.type # 0=onchain, 2=LN item['timestamp'] = req.time item['date'] = format_time(item['timestamp']) @@ -97,7 +98,8 @@ class QERequestListModel(QAbstractListModel): for item in self.requests: if item['key'] == key: req = self.wallet.get_request(key) - item['status'] = req.get_status_str(status) + item['status'] = status + item['status_str'] = req.get_status_str(status) index = self.index(i,0) - self.dataChanged.emit(index, index, [self._ROLE_RMAP['status']]) + self.dataChanged.emit(index, index, [self._ROLE_RMAP['status'], self._ROLE_RMAP['status_str']]) i = i + 1