mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
kivy: remove context menus, cleanup unused files
This commit is contained in:
parent
587f8aa487
commit
e9c32bad19
11 changed files with 206 additions and 601 deletions
|
@ -231,15 +231,14 @@
|
||||||
size: self.size
|
size: self.size
|
||||||
pos: self.pos
|
pos: self.pos
|
||||||
|
|
||||||
<CardItem@ToggleButtonBehavior+BoxLayout>
|
<CardItem@ButtonBehavior+BoxLayout>
|
||||||
size_hint: 1, None
|
size_hint: 1, None
|
||||||
height: '65dp'
|
height: '65dp'
|
||||||
group: 'requests'
|
group: 'requests'
|
||||||
padding: dp(12)
|
padding: dp(12)
|
||||||
spacing: dp(5)
|
spacing: dp(5)
|
||||||
screen: None
|
screen: None
|
||||||
on_state:
|
on_release: self.screen.show_item(args[0])
|
||||||
self.screen.show_menu(args[0]) if self.state == 'down' else self.screen.hide_menu()
|
|
||||||
canvas.before:
|
canvas.before:
|
||||||
Color:
|
Color:
|
||||||
rgba: (0.192, .498, 0.745, 1) if self.state == 'down' else (0.15, 0.15, 0.17, 1)
|
rgba: (0.192, .498, 0.745, 1) if self.state == 'down' else (0.15, 0.15, 0.17, 1)
|
||||||
|
|
|
@ -418,41 +418,6 @@ class ElectrumWindow(App):
|
||||||
self.request_popup.set_status(status)
|
self.request_popup.set_status(status)
|
||||||
self.request_popup.open()
|
self.request_popup.open()
|
||||||
|
|
||||||
def show_pr_details(self, req, status, is_invoice):
|
|
||||||
from electrum.util import format_time
|
|
||||||
requestor = req.get('requestor')
|
|
||||||
exp = req.get('exp')
|
|
||||||
memo = req.get('memo')
|
|
||||||
amount = req.get('amount')
|
|
||||||
fund = req.get('fund')
|
|
||||||
popup = Builder.load_file('electrum/gui/kivy/uix/ui_screens/invoice.kv')
|
|
||||||
popup.is_invoice = is_invoice
|
|
||||||
popup.amount = amount
|
|
||||||
popup.requestor = requestor if is_invoice else req.get('address')
|
|
||||||
popup.exp = format_time(exp) if exp else ''
|
|
||||||
popup.description = memo if memo else ''
|
|
||||||
popup.signature = req.get('signature', '')
|
|
||||||
popup.status = status
|
|
||||||
popup.fund = fund if fund else 0
|
|
||||||
txid = req.get('txid')
|
|
||||||
popup.tx_hash = txid or ''
|
|
||||||
popup.on_open = lambda: popup.ids.output_list.update(req.get('outputs', []))
|
|
||||||
popup.export = self.export_private_keys
|
|
||||||
popup.open()
|
|
||||||
|
|
||||||
def show_addr_details(self, req, status):
|
|
||||||
from electrum.util import format_time
|
|
||||||
fund = req.get('fund')
|
|
||||||
isaddr = 'y'
|
|
||||||
popup = Builder.load_file('electrum/gui/kivy/uix/ui_screens/invoice.kv')
|
|
||||||
popup.isaddr = isaddr
|
|
||||||
popup.is_invoice = False
|
|
||||||
popup.status = status
|
|
||||||
popup.requestor = req.get('address')
|
|
||||||
popup.fund = fund if fund else 0
|
|
||||||
popup.export = self.export_private_keys
|
|
||||||
popup.open()
|
|
||||||
|
|
||||||
def qr_dialog(self, title, data, show_text=False, text_for_clipboard=None):
|
def qr_dialog(self, title, data, show_text=False, text_for_clipboard=None):
|
||||||
from .uix.dialogs.qr_dialog import QRDialog
|
from .uix.dialogs.qr_dialog import QRDialog
|
||||||
def on_qr_failure():
|
def on_qr_failure():
|
||||||
|
@ -1035,28 +1000,6 @@ class ElectrumWindow(App):
|
||||||
popup = AmountDialog(show_max, amount, cb)
|
popup = AmountDialog(show_max, amount, cb)
|
||||||
popup.open()
|
popup.open()
|
||||||
|
|
||||||
def lightning_invoices_dialog(self, cb):
|
|
||||||
from .uix.dialogs.lightning_invoices import LightningInvoicesDialog
|
|
||||||
report = self.wallet.lnworker._list_invoices()
|
|
||||||
if not report['unsettled']:
|
|
||||||
self.show_info(_('No unsettled invoices. Type in an amount to generate a new one.'))
|
|
||||||
return
|
|
||||||
popup = LightningInvoicesDialog(report, cb)
|
|
||||||
popup.open()
|
|
||||||
|
|
||||||
def invoices_dialog(self, screen):
|
|
||||||
from .uix.dialogs.invoices import InvoicesDialog
|
|
||||||
if len(self.wallet.invoices.sorted_list()) == 0:
|
|
||||||
self.show_info(' '.join([
|
|
||||||
_('No saved invoices.'),
|
|
||||||
_('Signed invoices are saved automatically when you scan them.'),
|
|
||||||
_('You may also save unsigned requests or contact addresses using the save button.')
|
|
||||||
]))
|
|
||||||
return
|
|
||||||
popup = InvoicesDialog(self, screen, None)
|
|
||||||
popup.update()
|
|
||||||
popup.open()
|
|
||||||
|
|
||||||
def addresses_dialog(self):
|
def addresses_dialog(self):
|
||||||
from .uix.dialogs.addresses import AddressesDialog
|
from .uix.dialogs.addresses import AddressesDialog
|
||||||
if self._addresses_dialog is None:
|
if self._addresses_dialog is None:
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
#!python
|
|
||||||
#!/usr/bin/env python
|
|
||||||
from kivy.app import App
|
|
||||||
from kivy.uix.bubble import Bubble
|
|
||||||
from kivy.animation import Animation
|
|
||||||
from kivy.uix.floatlayout import FloatLayout
|
|
||||||
from kivy.lang import Builder
|
|
||||||
from kivy.factory import Factory
|
|
||||||
from kivy.clock import Clock
|
|
||||||
|
|
||||||
from electrum.gui.kivy.i18n import _
|
|
||||||
|
|
||||||
Builder.load_string('''
|
|
||||||
<MenuItem@Button>
|
|
||||||
background_normal: ''
|
|
||||||
background_color: (0.192, .498, 0.745, 1)
|
|
||||||
height: '48dp'
|
|
||||||
size_hint: 1, None
|
|
||||||
|
|
||||||
<ContextMenu>
|
|
||||||
size_hint: 1, None
|
|
||||||
height: '60dp'
|
|
||||||
pos: (0, 0)
|
|
||||||
show_arrow: False
|
|
||||||
arrow_pos: 'top_mid'
|
|
||||||
padding: 0
|
|
||||||
orientation: 'horizontal'
|
|
||||||
background_color: (0.1, 0.1, 0.1, 1)
|
|
||||||
background_image: ''
|
|
||||||
BoxLayout:
|
|
||||||
size_hint: 1, 1
|
|
||||||
height: '54dp'
|
|
||||||
padding: '0dp', '0dp'
|
|
||||||
spacing: '3dp'
|
|
||||||
orientation: 'horizontal'
|
|
||||||
id: buttons
|
|
||||||
''')
|
|
||||||
|
|
||||||
|
|
||||||
class MenuItem(Factory.Button):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class ContextMenu(Bubble):
|
|
||||||
|
|
||||||
def __init__(self, obj, action_list):
|
|
||||||
Bubble.__init__(self)
|
|
||||||
self.obj = obj
|
|
||||||
for k, v in action_list:
|
|
||||||
l = MenuItem()
|
|
||||||
l.text = _(k)
|
|
||||||
def func(f=v):
|
|
||||||
Clock.schedule_once(lambda dt: f(obj), 0.15)
|
|
||||||
l.on_release = func
|
|
||||||
self.ids.buttons.add_widget(l)
|
|
||||||
|
|
||||||
def hide(self):
|
|
||||||
if self.parent:
|
|
||||||
self.parent.hide_menu()
|
|
|
@ -3,6 +3,9 @@ from kivy.factory import Factory
|
||||||
from kivy.properties import ObjectProperty
|
from kivy.properties import ObjectProperty
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
from kivy.uix.popup import Popup
|
||||||
|
|
||||||
|
from electrum.gui.kivy.i18n import _
|
||||||
|
|
||||||
Builder.load_string('''
|
Builder.load_string('''
|
||||||
<AddressLabel@Label>
|
<AddressLabel@Label>
|
||||||
|
@ -95,11 +98,85 @@ Builder.load_string('''
|
||||||
default_size_hint: 1, None
|
default_size_hint: 1, None
|
||||||
size_hint_y: None
|
size_hint_y: None
|
||||||
height: self.minimum_height
|
height: self.minimum_height
|
||||||
|
|
||||||
|
<AddressPopup@Popup>:
|
||||||
|
address: ''
|
||||||
|
balance: ''
|
||||||
|
status: ''
|
||||||
|
pk: ''
|
||||||
|
BoxLayout:
|
||||||
|
orientation: 'vertical'
|
||||||
|
ScrollView:
|
||||||
|
GridLayout:
|
||||||
|
cols: 1
|
||||||
|
height: self.minimum_height
|
||||||
|
size_hint_y: None
|
||||||
|
padding: '10dp'
|
||||||
|
spacing: '10dp'
|
||||||
|
GridLayout:
|
||||||
|
cols: 1
|
||||||
|
size_hint_y: None
|
||||||
|
height: self.minimum_height
|
||||||
|
spacing: '10dp'
|
||||||
|
BoxLabel:
|
||||||
|
text: _('Address')
|
||||||
|
value: root.address
|
||||||
|
BoxLabel:
|
||||||
|
text: _('Balance')
|
||||||
|
value: root.balance
|
||||||
|
BoxLabel:
|
||||||
|
text: _('Status')
|
||||||
|
value: root.status
|
||||||
|
TopLabel:
|
||||||
|
text: _('Private Key')
|
||||||
|
RefLabel:
|
||||||
|
id: pk_label
|
||||||
|
touched: True if not self.touched else True
|
||||||
|
data: root.pk
|
||||||
|
Widget:
|
||||||
|
size_hint: 1, 0.1
|
||||||
|
BoxLayout:
|
||||||
|
size_hint: 1, None
|
||||||
|
height: '48dp'
|
||||||
|
Button:
|
||||||
|
size_hint: 0.5, None
|
||||||
|
height: '48dp'
|
||||||
|
text: _('Hide key') if pk_label.data else _('Show key')
|
||||||
|
on_release:
|
||||||
|
setattr(pk_label, 'data', '') if pk_label.data else root.do_export(pk_label)
|
||||||
|
Button:
|
||||||
|
size_hint: 0.5, None
|
||||||
|
height: '48dp'
|
||||||
|
text: _('Use')
|
||||||
|
on_release: root.do_use()
|
||||||
|
Button:
|
||||||
|
size_hint: 0.5, None
|
||||||
|
height: '48dp'
|
||||||
|
text: _('Close')
|
||||||
|
on_release: root.dismiss()
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
from electrum.gui.kivy.i18n import _
|
|
||||||
from electrum.gui.kivy.uix.context_menu import ContextMenu
|
class AddressPopup(Popup):
|
||||||
|
|
||||||
|
def __init__(self, parent, address, balance, status, **kwargs):
|
||||||
|
super(AddressPopup, self).__init__(**kwargs)
|
||||||
|
self.title = _('Address')
|
||||||
|
self.parent_dialog = parent
|
||||||
|
self.app = parent.app
|
||||||
|
self.address = address
|
||||||
|
self.status = status
|
||||||
|
self.balance = self.app.format_amount_and_units(balance)
|
||||||
|
|
||||||
|
def do_use(self):
|
||||||
|
self.dismiss()
|
||||||
|
self.parent_dialog.dismiss()
|
||||||
|
self.app.switch_to('receive')
|
||||||
|
self.app.receive_screen.set_address(self.address)
|
||||||
|
|
||||||
|
def do_export(self, pk_label):
|
||||||
|
self.app.export_private_keys(pk_label, self.address)
|
||||||
|
|
||||||
|
|
||||||
class AddressesDialog(Factory.Popup):
|
class AddressesDialog(Factory.Popup):
|
||||||
|
@ -107,7 +184,6 @@ class AddressesDialog(Factory.Popup):
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
Factory.Popup.__init__(self)
|
Factory.Popup.__init__(self)
|
||||||
self.app = app
|
self.app = app
|
||||||
self.context_menu = None
|
|
||||||
|
|
||||||
def get_card(self, addr, balance, is_used, label):
|
def get_card(self, addr, balance, is_used, label):
|
||||||
ci = {}
|
ci = {}
|
||||||
|
@ -119,7 +195,6 @@ class AddressesDialog(Factory.Popup):
|
||||||
return ci
|
return ci
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.menu_actions = [(_('Use'), self.do_use), (_('Details'), self.do_view)]
|
|
||||||
wallet = self.app.wallet
|
wallet = self.app.wallet
|
||||||
if self.show_change == 0:
|
if self.show_change == 0:
|
||||||
_list = wallet.get_receiving_addresses()
|
_list = wallet.get_receiving_addresses()
|
||||||
|
@ -150,30 +225,12 @@ class AddressesDialog(Factory.Popup):
|
||||||
if not n:
|
if not n:
|
||||||
self.app.show_error('No address matching your search')
|
self.app.show_error('No address matching your search')
|
||||||
|
|
||||||
def do_use(self, obj):
|
def show_item(self, obj):
|
||||||
self.hide_menu()
|
address = obj.address
|
||||||
self.dismiss()
|
c, u, x = self.app.wallet.get_addr_balance(address)
|
||||||
self.app.switch_to('receive')
|
|
||||||
self.app.receive_screen.set_address(obj.address)
|
|
||||||
|
|
||||||
def do_view(self, obj):
|
|
||||||
req = { 'address': obj.address, 'status' : obj.status }
|
|
||||||
status = obj.status
|
|
||||||
c, u, x = self.app.wallet.get_addr_balance(obj.address)
|
|
||||||
balance = c + u + x
|
balance = c + u + x
|
||||||
if balance > 0:
|
d = AddressPopup(self, address, balance, obj.status)
|
||||||
req['fund'] = balance
|
d.open()
|
||||||
self.app.show_addr_details(req, status)
|
|
||||||
|
|
||||||
def ext_search(self, card, search):
|
def ext_search(self, card, search):
|
||||||
return card['memo'].find(search) >= 0 or card['amount'].find(search) >= 0
|
return card['memo'].find(search) >= 0 or card['amount'].find(search) >= 0
|
||||||
|
|
||||||
def show_menu(self, obj):
|
|
||||||
self.hide_menu()
|
|
||||||
self.context_menu = ContextMenu(obj, self.menu_actions)
|
|
||||||
self.ids.box.add_widget(self.context_menu)
|
|
||||||
|
|
||||||
def hide_menu(self):
|
|
||||||
if self.context_menu is not None:
|
|
||||||
self.ids.box.remove_widget(self.context_menu)
|
|
||||||
self.context_menu = None
|
|
||||||
|
|
|
@ -1,169 +0,0 @@
|
||||||
from kivy.app import App
|
|
||||||
from kivy.factory import Factory
|
|
||||||
from kivy.properties import ObjectProperty
|
|
||||||
from kivy.lang import Builder
|
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
Builder.load_string('''
|
|
||||||
<InvoicesLabel@Label>
|
|
||||||
#color: .305, .309, .309, 1
|
|
||||||
text_size: self.width, None
|
|
||||||
halign: 'left'
|
|
||||||
valign: 'top'
|
|
||||||
|
|
||||||
<InvoiceItem@CardItem>
|
|
||||||
requestor: ''
|
|
||||||
memo: ''
|
|
||||||
amount: ''
|
|
||||||
status: ''
|
|
||||||
date: ''
|
|
||||||
icon: 'atlas://electrum/gui/kivy/theming/light/important'
|
|
||||||
Image:
|
|
||||||
id: icon
|
|
||||||
source: root.icon
|
|
||||||
size_hint: None, 1
|
|
||||||
width: self.height *.54
|
|
||||||
mipmap: True
|
|
||||||
BoxLayout:
|
|
||||||
spacing: '8dp'
|
|
||||||
height: '32dp'
|
|
||||||
orientation: 'vertical'
|
|
||||||
Widget
|
|
||||||
InvoicesLabel:
|
|
||||||
text: root.requestor
|
|
||||||
shorten: True
|
|
||||||
Widget
|
|
||||||
InvoicesLabel:
|
|
||||||
text: root.memo
|
|
||||||
color: .699, .699, .699, 1
|
|
||||||
font_size: '13sp'
|
|
||||||
shorten: True
|
|
||||||
Widget
|
|
||||||
BoxLayout:
|
|
||||||
spacing: '8dp'
|
|
||||||
height: '32dp'
|
|
||||||
orientation: 'vertical'
|
|
||||||
Widget
|
|
||||||
InvoicesLabel:
|
|
||||||
text: root.amount
|
|
||||||
font_size: '15sp'
|
|
||||||
halign: 'right'
|
|
||||||
width: '110sp'
|
|
||||||
Widget
|
|
||||||
InvoicesLabel:
|
|
||||||
text: root.status
|
|
||||||
font_size: '13sp'
|
|
||||||
halign: 'right'
|
|
||||||
color: .699, .699, .699, 1
|
|
||||||
Widget
|
|
||||||
|
|
||||||
|
|
||||||
<InvoicesDialog@Popup>
|
|
||||||
id: popup
|
|
||||||
title: _('Invoices')
|
|
||||||
BoxLayout:
|
|
||||||
id: box
|
|
||||||
orientation: 'vertical'
|
|
||||||
spacing: '1dp'
|
|
||||||
ScrollView:
|
|
||||||
GridLayout:
|
|
||||||
cols: 1
|
|
||||||
id: invoices_container
|
|
||||||
size_hint: 1, None
|
|
||||||
height: self.minimum_height
|
|
||||||
spacing: '2dp'
|
|
||||||
padding: '12dp'
|
|
||||||
''')
|
|
||||||
|
|
||||||
from kivy.properties import BooleanProperty
|
|
||||||
from electrum.gui.kivy.i18n import _
|
|
||||||
from electrum.util import format_time
|
|
||||||
from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED
|
|
||||||
from electrum.gui.kivy.uix.context_menu import ContextMenu
|
|
||||||
|
|
||||||
invoice_text = {
|
|
||||||
PR_UNPAID:_('Pending'),
|
|
||||||
PR_UNKNOWN:_('Unknown'),
|
|
||||||
PR_PAID:_('Paid'),
|
|
||||||
PR_EXPIRED:_('Expired')
|
|
||||||
}
|
|
||||||
pr_icon = {
|
|
||||||
PR_UNPAID: 'atlas://electrum/gui/kivy/theming/light/important',
|
|
||||||
PR_UNKNOWN: 'atlas://electrum/gui/kivy/theming/light/important',
|
|
||||||
PR_PAID: 'atlas://electrum/gui/kivy/theming/light/confirmed',
|
|
||||||
PR_EXPIRED: 'atlas://electrum/gui/kivy/theming/light/close'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class InvoicesDialog(Factory.Popup):
|
|
||||||
|
|
||||||
def __init__(self, app, screen, callback):
|
|
||||||
Factory.Popup.__init__(self)
|
|
||||||
self.app = app
|
|
||||||
self.screen = screen
|
|
||||||
self.callback = callback
|
|
||||||
self.cards = {}
|
|
||||||
self.context_menu = None
|
|
||||||
|
|
||||||
def get_card(self, pr):
|
|
||||||
key = pr.get_id()
|
|
||||||
ci = self.cards.get(key)
|
|
||||||
if ci is None:
|
|
||||||
ci = Factory.InvoiceItem()
|
|
||||||
ci.key = key
|
|
||||||
ci.screen = self
|
|
||||||
self.cards[key] = ci
|
|
||||||
ci.requestor = pr.get_requestor()
|
|
||||||
ci.memo = pr.get_memo()
|
|
||||||
amount = pr.get_amount()
|
|
||||||
if amount:
|
|
||||||
ci.amount = self.app.format_amount_and_units(amount)
|
|
||||||
status = self.app.wallet.invoices.get_status(ci.key)
|
|
||||||
ci.status = invoice_text[status]
|
|
||||||
ci.icon = pr_icon[status]
|
|
||||||
else:
|
|
||||||
ci.amount = _('No Amount')
|
|
||||||
ci.status = ''
|
|
||||||
exp = pr.get_expiration_date()
|
|
||||||
ci.date = format_time(exp) if exp else _('Never')
|
|
||||||
return ci
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
self.menu_actions = [('Pay', self.do_pay), ('Details', self.do_view), ('Delete', self.do_delete)]
|
|
||||||
invoices_list = self.ids.invoices_container
|
|
||||||
invoices_list.clear_widgets()
|
|
||||||
_list = self.app.wallet.invoices.sorted_list()
|
|
||||||
for pr in _list:
|
|
||||||
ci = self.get_card(pr)
|
|
||||||
invoices_list.add_widget(ci)
|
|
||||||
|
|
||||||
def do_pay(self, obj):
|
|
||||||
self.hide_menu()
|
|
||||||
self.dismiss()
|
|
||||||
pr = self.app.wallet.invoices.get(obj.key)
|
|
||||||
self.app.on_pr(pr)
|
|
||||||
|
|
||||||
def do_view(self, obj):
|
|
||||||
pr = self.app.wallet.invoices.get(obj.key)
|
|
||||||
pr.verify(self.app.wallet.contacts)
|
|
||||||
self.app.show_pr_details(pr.get_dict(), obj.status, True)
|
|
||||||
|
|
||||||
def do_delete(self, obj):
|
|
||||||
from .question import Question
|
|
||||||
def cb(result):
|
|
||||||
if result:
|
|
||||||
self.app.wallet.invoices.remove(obj.key)
|
|
||||||
self.hide_menu()
|
|
||||||
self.update()
|
|
||||||
d = Question(_('Delete invoice?'), cb)
|
|
||||||
d.open()
|
|
||||||
|
|
||||||
def show_menu(self, obj):
|
|
||||||
self.hide_menu()
|
|
||||||
self.context_menu = ContextMenu(obj, self.menu_actions)
|
|
||||||
self.ids.box.add_widget(self.context_menu)
|
|
||||||
|
|
||||||
def hide_menu(self):
|
|
||||||
if self.context_menu is not None:
|
|
||||||
self.ids.box.remove_widget(self.context_menu)
|
|
||||||
self.context_menu = None
|
|
|
@ -4,10 +4,10 @@ from kivy.lang import Builder
|
||||||
from kivy.factory import Factory
|
from kivy.factory import Factory
|
||||||
from kivy.uix.popup import Popup
|
from kivy.uix.popup import Popup
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from electrum.gui.kivy.uix.context_menu import ContextMenu
|
|
||||||
from electrum.util import bh2u
|
from electrum.util import bh2u
|
||||||
from electrum.lnutil import LOCAL, REMOTE, format_short_channel_id
|
from electrum.lnutil import LOCAL, REMOTE, format_short_channel_id
|
||||||
from electrum.gui.kivy.i18n import _
|
from electrum.gui.kivy.i18n import _
|
||||||
|
from .question import Question
|
||||||
|
|
||||||
Builder.load_string(r'''
|
Builder.load_string(r'''
|
||||||
<LightningChannelItem@CardItem>
|
<LightningChannelItem@CardItem>
|
||||||
|
@ -71,38 +71,11 @@ Builder.load_string(r'''
|
||||||
text: _('New channel...')
|
text: _('New channel...')
|
||||||
on_press: popup.app.popup_dialog('lightning_open_channel_dialog')
|
on_press: popup.app.popup_dialog('lightning_open_channel_dialog')
|
||||||
|
|
||||||
<ChannelDetailsItem@BoxLayout>:
|
|
||||||
canvas.before:
|
|
||||||
Color:
|
|
||||||
rgba: 0.5, 0.5, 0.5, 1
|
|
||||||
Rectangle:
|
|
||||||
size: self.size
|
|
||||||
pos: self.pos
|
|
||||||
value: ''
|
|
||||||
Label:
|
|
||||||
text: root.value
|
|
||||||
text_size: self.size # this makes the text not overflow, but wrap
|
|
||||||
|
|
||||||
<ChannelDetailsRow@BoxLayout>:
|
|
||||||
keyName: ''
|
|
||||||
value: ''
|
|
||||||
ChannelDetailsItem:
|
|
||||||
value: root.keyName
|
|
||||||
size_hint_x: 0.5 # this makes the column narrower
|
|
||||||
|
|
||||||
# see https://blog.kivy.org/2014/07/wrapping-text-in-kivys-label/
|
|
||||||
ScrollView:
|
|
||||||
Label:
|
|
||||||
text: root.value
|
|
||||||
size_hint_y: None
|
|
||||||
text_size: self.width, None
|
|
||||||
height: self.texture_size[1]
|
|
||||||
|
|
||||||
<ChannelDetailsList@RecycleView>:
|
<ChannelDetailsList@RecycleView>:
|
||||||
scroll_type: ['bars', 'content']
|
scroll_type: ['bars', 'content']
|
||||||
scroll_wheel_distance: dp(114)
|
scroll_wheel_distance: dp(114)
|
||||||
bar_width: dp(10)
|
bar_width: dp(10)
|
||||||
viewclass: 'ChannelDetailsRow'
|
viewclass: 'BoxLabel'
|
||||||
RecycleBoxLayout:
|
RecycleBoxLayout:
|
||||||
default_size: None, dp(56)
|
default_size: None, dp(56)
|
||||||
default_size_hint: 1, None
|
default_size_hint: 1, None
|
||||||
|
@ -114,64 +87,102 @@ Builder.load_string(r'''
|
||||||
<ChannelDetailsPopup@Popup>:
|
<ChannelDetailsPopup@Popup>:
|
||||||
id: popuproot
|
id: popuproot
|
||||||
data: []
|
data: []
|
||||||
ChannelDetailsList:
|
BoxLayout:
|
||||||
data: popuproot.data
|
orientation: 'vertical'
|
||||||
|
ScrollView:
|
||||||
|
ChannelDetailsList:
|
||||||
|
data: popuproot.data
|
||||||
|
Widget:
|
||||||
|
size_hint: 1, 0.1
|
||||||
|
BoxLayout:
|
||||||
|
size_hint: 1, None
|
||||||
|
height: '48dp'
|
||||||
|
Button:
|
||||||
|
size_hint: 0.5, None
|
||||||
|
height: '48dp'
|
||||||
|
text: _('Close channel')
|
||||||
|
on_release: root.close()
|
||||||
|
Button:
|
||||||
|
size_hint: 0.5, None
|
||||||
|
height: '48dp'
|
||||||
|
text: _('Force-close')
|
||||||
|
on_release: root.force_close()
|
||||||
|
Button:
|
||||||
|
size_hint: 0.5, None
|
||||||
|
height: '48dp'
|
||||||
|
text: _('Dismiss')
|
||||||
|
on_release: root.dismiss()
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
class ChannelDetailsPopup(Popup):
|
class ChannelDetailsPopup(Popup):
|
||||||
def __init__(self, data, **kwargs):
|
|
||||||
|
def __init__(self, chan, app, **kwargs):
|
||||||
super(ChannelDetailsPopup,self).__init__(**kwargs)
|
super(ChannelDetailsPopup,self).__init__(**kwargs)
|
||||||
self.data = data
|
|
||||||
|
|
||||||
class LightningChannelsDialog(Factory.Popup):
|
|
||||||
def __init__(self, app):
|
|
||||||
super(LightningChannelsDialog, self).__init__()
|
|
||||||
self.clocks = []
|
|
||||||
self.app = app
|
self.app = app
|
||||||
self.context_menu = None
|
self.chan = chan
|
||||||
self.app.wallet.network.register_callback(self.on_channels, ['channels'])
|
self.title = _('Channel details')
|
||||||
self.app.wallet.network.register_callback(self.on_channel, ['channel'])
|
self.data = [{'text': key, 'value': str(value)} for key, value in self.details().items()]
|
||||||
self.update()
|
|
||||||
|
|
||||||
def show_channel_details(self, obj):
|
def details(self):
|
||||||
p = Factory.ChannelDetailsPopup()
|
chan = self.chan
|
||||||
p.title = _('Details for channel ') + format_short_channel_id(obj.chan.short_channel_id)
|
return {
|
||||||
p.data = [{'keyName': key, 'value': str(obj.details[key])} for key in obj.details.keys()]
|
_('Short Chan ID'): format_short_channel_id(chan.short_channel_id),
|
||||||
p.open()
|
_('Initiator'): 'Local' if chan.constraints.is_initiator else 'Remote',
|
||||||
|
_('State'): chan.get_state(),
|
||||||
|
_('Capacity'): self.app.format_amount_and_units(chan.constraints.capacity),
|
||||||
|
_('Can send'): self.app.format_amount_and_units(chan.available_to_spend(LOCAL) // 1000),
|
||||||
|
_('Current feerate'): str(chan.get_latest_feerate(LOCAL)),
|
||||||
|
_('Node ID'): bh2u(chan.node_id),
|
||||||
|
_('Channel ID'): bh2u(chan.channel_id),
|
||||||
|
_('Funding TXID'): chan.funding_outpoint.txid,
|
||||||
|
}
|
||||||
|
|
||||||
def close_channel(self, obj):
|
def close(self):
|
||||||
|
Question(_('Close channel?'), self._close).open()
|
||||||
|
|
||||||
|
def _close(self, b):
|
||||||
|
if not b:
|
||||||
|
return
|
||||||
loop = self.app.wallet.network.asyncio_loop
|
loop = self.app.wallet.network.asyncio_loop
|
||||||
coro = asyncio.run_coroutine_threadsafe(self.app.wallet.lnworker.close_channel(obj._chan.channel_id), loop)
|
coro = asyncio.run_coroutine_threadsafe(self.app.wallet.lnworker.close_channel(self._chan.channel_id), loop)
|
||||||
try:
|
try:
|
||||||
coro.result(5)
|
coro.result(5)
|
||||||
self.app.show_info(_('Channel closed'))
|
self.app.show_info(_('Channel closed'))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.app.show_info(_('Could not close channel: ') + repr(e)) # repr because str(Exception()) == ''
|
self.app.show_info(_('Could not close channel: ') + repr(e)) # repr because str(Exception()) == ''
|
||||||
|
|
||||||
def force_close_channel(self, obj):
|
def force_close(self):
|
||||||
if obj._chan.get_state() == 'CLOSED':
|
Question(_('Force-close channel?'), self._force_close).open()
|
||||||
|
|
||||||
|
def _force_close(self, b):
|
||||||
|
if not b:
|
||||||
|
return
|
||||||
|
if self.chan.get_state() == 'CLOSED':
|
||||||
self.app.show_error(_('Channel already closed'))
|
self.app.show_error(_('Channel already closed'))
|
||||||
return
|
return
|
||||||
loop = self.app.wallet.network.asyncio_loop
|
loop = self.app.wallet.network.asyncio_loop
|
||||||
coro = asyncio.run_coroutine_threadsafe(self.app.wallet.lnworker.force_close_channel(obj._chan.channel_id), loop)
|
coro = asyncio.run_coroutine_threadsafe(self.app.wallet.lnworker.force_close_channel(self.chan.channel_id), loop)
|
||||||
try:
|
try:
|
||||||
coro.result(1)
|
coro.result(1)
|
||||||
self.app.show_info(_('Channel closed, you may need to wait at least {} blocks, because of CSV delays'.format(obj._chan.config[REMOTE].to_self_delay)))
|
self.app.show_info(_('Channel closed, you may need to wait at least {} blocks, because of CSV delays'.format(self.chan.config[REMOTE].to_self_delay)))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.app.show_info(_('Could not force close channel: ') + repr(e)) # repr because str(Exception()) == ''
|
self.app.show_info(_('Could not force close channel: ') + repr(e)) # repr because str(Exception()) == ''
|
||||||
|
|
||||||
def show_menu(self, obj):
|
|
||||||
self.hide_menu()
|
|
||||||
self.context_menu = ContextMenu(obj, [
|
|
||||||
(_("Force close"), self.force_close_channel),
|
|
||||||
(_("Co-op close"), self.close_channel),
|
|
||||||
(_("Details"), self.show_channel_details)])
|
|
||||||
self.ids.box.add_widget(self.context_menu)
|
|
||||||
|
|
||||||
def hide_menu(self):
|
class LightningChannelsDialog(Factory.Popup):
|
||||||
if self.context_menu is not None:
|
|
||||||
self.ids.box.remove_widget(self.context_menu)
|
def __init__(self, app):
|
||||||
self.context_menu = None
|
super(LightningChannelsDialog, self).__init__()
|
||||||
|
self.clocks = []
|
||||||
|
self.app = app
|
||||||
|
self.app.wallet.network.register_callback(self.on_channels, ['channels'])
|
||||||
|
self.app.wallet.network.register_callback(self.on_channel, ['channel'])
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def show_item(self, obj):
|
||||||
|
p = ChannelDetailsPopup(obj._chan, self.app)
|
||||||
|
p.open()
|
||||||
|
|
||||||
def format_fields(self, chan):
|
def format_fields(self, chan):
|
||||||
labels = {}
|
labels = {}
|
||||||
|
@ -213,18 +224,6 @@ class LightningChannelsDialog(Factory.Popup):
|
||||||
item = Factory.LightningChannelItem()
|
item = Factory.LightningChannelItem()
|
||||||
item.screen = self
|
item.screen = self
|
||||||
item.active = i.node_id in lnworker.peers
|
item.active = i.node_id in lnworker.peers
|
||||||
item.details = self.channel_details(i)
|
|
||||||
item._chan = i
|
item._chan = i
|
||||||
self.update_item(item)
|
self.update_item(item)
|
||||||
channel_cards.add_widget(item)
|
channel_cards.add_widget(item)
|
||||||
|
|
||||||
def channel_details(self, chan):
|
|
||||||
return {_('Node ID'): bh2u(chan.node_id),
|
|
||||||
_('Channel ID'): bh2u(chan.channel_id),
|
|
||||||
_('Capacity'): self.app.format_amount_and_units(chan.constraints.capacity),
|
|
||||||
_('Funding TXID'): chan.funding_outpoint.txid,
|
|
||||||
_('Short Chan ID'): bh2u(chan.short_channel_id) if chan.short_channel_id else _('Not available'),
|
|
||||||
_('Available to spend'): self.app.format_amount_and_units(chan.available_to_spend(LOCAL) // 1000),
|
|
||||||
_('State'): chan.get_state(),
|
|
||||||
_('Initiator'): 'Opened/funded by us' if chan.constraints.is_initiator else 'Opened/funded by remote party',
|
|
||||||
_('Current feerate'): chan.get_latest_feerate(LOCAL)}
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
from kivy.factory import Factory
|
|
||||||
from kivy.lang import Builder
|
|
||||||
from electrum.gui.kivy.i18n import _
|
|
||||||
from kivy.uix.recycleview import RecycleView
|
|
||||||
from electrum.gui.kivy.uix.context_menu import ContextMenu
|
|
||||||
|
|
||||||
Builder.load_string('''
|
|
||||||
<Item@CardItem>
|
|
||||||
addr: ''
|
|
||||||
desc: ''
|
|
||||||
screen: None
|
|
||||||
BoxLayout:
|
|
||||||
orientation: 'vertical'
|
|
||||||
Label
|
|
||||||
text: root.addr
|
|
||||||
text_size: self.width, None
|
|
||||||
shorten: True
|
|
||||||
Label
|
|
||||||
text: root.desc if root.desc else _('No description')
|
|
||||||
text_size: self.width, None
|
|
||||||
shorten: True
|
|
||||||
font_size: '10dp'
|
|
||||||
|
|
||||||
<LightningInvoicesDialog@Popup>
|
|
||||||
id: popup
|
|
||||||
title: _('Lightning Invoices')
|
|
||||||
BoxLayout:
|
|
||||||
orientation: 'vertical'
|
|
||||||
id: box
|
|
||||||
RecycleView:
|
|
||||||
viewclass: 'Item'
|
|
||||||
id: recycleview
|
|
||||||
data: []
|
|
||||||
RecycleBoxLayout:
|
|
||||||
default_size: None, dp(56)
|
|
||||||
default_size_hint: 1, None
|
|
||||||
size_hint_y: None
|
|
||||||
height: self.minimum_height
|
|
||||||
orientation: 'vertical'
|
|
||||||
''')
|
|
||||||
|
|
||||||
class LightningInvoicesDialog(Factory.Popup):
|
|
||||||
|
|
||||||
def __init__(self, report, callback):
|
|
||||||
super().__init__()
|
|
||||||
self.context_menu = None
|
|
||||||
self.callback = callback
|
|
||||||
self.menu_actions = [(_('Show'), self.do_show)]
|
|
||||||
for addr, preimage, pay_req in report['unsettled']:
|
|
||||||
self.ids.recycleview.data.append({'screen': self, 'addr': pay_req, 'desc': dict(addr.tags).get('d', '')})
|
|
||||||
|
|
||||||
def do_show(self, obj):
|
|
||||||
self.hide_menu()
|
|
||||||
self.dismiss()
|
|
||||||
self.callback(obj.addr)
|
|
||||||
|
|
||||||
def show_menu(self, obj):
|
|
||||||
self.hide_menu()
|
|
||||||
self.context_menu = ContextMenu(obj, self.menu_actions)
|
|
||||||
self.ids.box.add_widget(self.context_menu)
|
|
||||||
|
|
||||||
def hide_menu(self):
|
|
||||||
if self.context_menu is not None:
|
|
||||||
self.ids.box.remove_widget(self.context_menu)
|
|
||||||
self.context_menu = None
|
|
|
@ -42,30 +42,33 @@ Builder.load_string('''
|
||||||
Button:
|
Button:
|
||||||
size_hint: 1, None
|
size_hint: 1, None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
text: _('Copy')
|
text: _('Delete')
|
||||||
on_release:
|
on_release: root.delete_dialog()
|
||||||
root.copy_to_clipboard()
|
IconButton:
|
||||||
|
icon: 'atlas://electrum/gui/kivy/theming/light/copy'
|
||||||
|
size_hint: 0.5, None
|
||||||
|
height: '48dp'
|
||||||
|
on_release: root.copy_to_clipboard()
|
||||||
IconButton:
|
IconButton:
|
||||||
icon: 'atlas://electrum/gui/kivy/theming/light/share'
|
icon: 'atlas://electrum/gui/kivy/theming/light/share'
|
||||||
size_hint: 0.6, None
|
size_hint: 0.5, None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
on_release: s.parent.do_share()
|
on_release: root.do_share()
|
||||||
Button:
|
Button:
|
||||||
size_hint: 1, None
|
size_hint: 1, None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
text: _('Close')
|
text: _('Close')
|
||||||
on_release:
|
on_release: popup.dismiss()
|
||||||
popup.dismiss()
|
|
||||||
''')
|
''')
|
||||||
|
|
||||||
class RequestDialog(Factory.Popup):
|
class RequestDialog(Factory.Popup):
|
||||||
|
|
||||||
def __init__(self, title, data, key):
|
def __init__(self, title, data, key):
|
||||||
Factory.Popup.__init__(self)
|
Factory.Popup.__init__(self)
|
||||||
self.app = App.get_running_app()
|
self.app = App.get_running_app()
|
||||||
self.title = title
|
self.title = title
|
||||||
self.data = data
|
self.data = data
|
||||||
self.key = key
|
self.key = key
|
||||||
#self.text_for_clipboard = text_for_clipboard if text_for_clipboard else data
|
|
||||||
|
|
||||||
def on_open(self):
|
def on_open(self):
|
||||||
self.ids.qr.set_data(self.data)
|
self.ids.qr.set_data(self.data)
|
||||||
|
@ -80,3 +83,17 @@ class RequestDialog(Factory.Popup):
|
||||||
Clipboard.copy(self.data)
|
Clipboard.copy(self.data)
|
||||||
msg = _('Text copied to clipboard.')
|
msg = _('Text copied to clipboard.')
|
||||||
Clock.schedule_once(lambda dt: self.app.show_info(msg))
|
Clock.schedule_once(lambda dt: self.app.show_info(msg))
|
||||||
|
|
||||||
|
def do_share(self):
|
||||||
|
self.app.do_share(self.data, _("Share Bitcoin Request"))
|
||||||
|
self.dismiss()
|
||||||
|
|
||||||
|
def delete_dialog(self):
|
||||||
|
from .question import Question
|
||||||
|
def cb(result):
|
||||||
|
if result:
|
||||||
|
self.app.wallet.delete_request(self.key)
|
||||||
|
self.dismiss()
|
||||||
|
self.app.receive_screen.update()
|
||||||
|
d = Question(_('Delete request?'), cb)
|
||||||
|
d.open()
|
||||||
|
|
|
@ -98,6 +98,11 @@ Builder.load_string('''
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
icon: 'atlas://electrum/gui/kivy/theming/light/qrcode'
|
icon: 'atlas://electrum/gui/kivy/theming/light/qrcode'
|
||||||
on_release: root.show_qr()
|
on_release: root.show_qr()
|
||||||
|
Button:
|
||||||
|
size_hint: 0.5, None
|
||||||
|
height: '48dp'
|
||||||
|
text: _('Label')
|
||||||
|
on_release: root.label_dialog()
|
||||||
Button:
|
Button:
|
||||||
size_hint: 0.5, None
|
size_hint: 0.5, None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
|
@ -271,3 +276,14 @@ class TxDialog(Factory.Popup):
|
||||||
self.dismiss()
|
self.dismiss()
|
||||||
d = Question(question, on_prompt)
|
d = Question(question, on_prompt)
|
||||||
d.open()
|
d.open()
|
||||||
|
|
||||||
|
def label_dialog(self):
|
||||||
|
from .label_dialog import LabelDialog
|
||||||
|
key = self.tx.txid()
|
||||||
|
text = self.app.wallet.get_label(key)
|
||||||
|
def callback(text):
|
||||||
|
self.app.wallet.set_label(key, text)
|
||||||
|
self.update()
|
||||||
|
self.app.history_screen.update()
|
||||||
|
d = LabelDialog(_('Enter Transaction Label'), text, callback)
|
||||||
|
d.open()
|
||||||
|
|
|
@ -33,7 +33,6 @@ from electrum import simple_config
|
||||||
from electrum.lnaddr import lndecode
|
from electrum.lnaddr import lndecode
|
||||||
from electrum.lnutil import RECEIVED, SENT, PaymentFailure
|
from electrum.lnutil import RECEIVED, SENT, PaymentFailure
|
||||||
|
|
||||||
from .context_menu import ContextMenu
|
|
||||||
from .dialogs.question import Question
|
from .dialogs.question import Question
|
||||||
from .dialogs.lightning_open_channel import LightningOpenChannelDialog
|
from .dialogs.lightning_open_channel import LightningOpenChannelDialog
|
||||||
|
|
||||||
|
@ -55,8 +54,6 @@ class CScreen(Factory.Screen):
|
||||||
action_view = ObjectProperty(None)
|
action_view = ObjectProperty(None)
|
||||||
loaded = False
|
loaded = False
|
||||||
kvname = None
|
kvname = None
|
||||||
context_menu = None
|
|
||||||
menu_actions = []
|
|
||||||
app = App.get_running_app()
|
app = App.get_running_app()
|
||||||
|
|
||||||
def _change_action_view(self):
|
def _change_action_view(self):
|
||||||
|
@ -94,17 +91,7 @@ class CScreen(Factory.Screen):
|
||||||
self.dispatch('on_deactivate')
|
self.dispatch('on_deactivate')
|
||||||
|
|
||||||
def on_deactivate(self):
|
def on_deactivate(self):
|
||||||
self.hide_menu()
|
pass
|
||||||
|
|
||||||
def hide_menu(self):
|
|
||||||
if self.context_menu is not None:
|
|
||||||
self.remove_widget(self.context_menu)
|
|
||||||
self.context_menu = None
|
|
||||||
|
|
||||||
def show_menu(self, obj):
|
|
||||||
self.hide_menu()
|
|
||||||
self.context_menu = ContextMenu(obj, self.menu_actions)
|
|
||||||
self.add_widget(self.context_menu)
|
|
||||||
|
|
||||||
|
|
||||||
# note: this list needs to be kept in sync with another in qt
|
# note: this list needs to be kept in sync with another in qt
|
||||||
|
@ -130,24 +117,15 @@ class HistoryScreen(CScreen):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.ra_dialog = None
|
self.ra_dialog = None
|
||||||
super(HistoryScreen, self).__init__(**kwargs)
|
super(HistoryScreen, self).__init__(**kwargs)
|
||||||
self.menu_actions = [ ('Label', self.label_dialog), ('Details', self.show_tx)]
|
|
||||||
|
|
||||||
def show_tx(self, obj):
|
def show_item(self, obj):
|
||||||
|
print(obj)
|
||||||
key = obj.key
|
key = obj.key
|
||||||
tx = self.app.wallet.db.get_transaction(key)
|
tx = self.app.wallet.db.get_transaction(key)
|
||||||
if not tx:
|
if not tx:
|
||||||
return
|
return
|
||||||
self.app.tx_dialog(tx)
|
self.app.tx_dialog(tx)
|
||||||
|
|
||||||
def label_dialog(self, obj):
|
|
||||||
from .dialogs.label_dialog import LabelDialog
|
|
||||||
key = obj.key
|
|
||||||
text = self.app.wallet.get_label(key)
|
|
||||||
def callback(text):
|
|
||||||
self.app.wallet.set_label(key, text)
|
|
||||||
self.update()
|
|
||||||
d = LabelDialog(_('Enter Transaction Label'), text, callback)
|
|
||||||
d.open()
|
|
||||||
|
|
||||||
def get_card(self, tx_item): #tx_hash, tx_mined_status, value, balance):
|
def get_card(self, tx_item): #tx_hash, tx_mined_status, value, balance):
|
||||||
is_lightning = tx_item.get('lightning', False)
|
is_lightning = tx_item.get('lightning', False)
|
||||||
|
@ -406,7 +384,6 @@ class ReceiveScreen(CScreen):
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(ReceiveScreen, self).__init__(**kwargs)
|
super(ReceiveScreen, self).__init__(**kwargs)
|
||||||
self.menu_actions = [(_('Show'), self.do_show), (_('Delete'), self.delete_request_dialog)]
|
|
||||||
Clock.schedule_interval(lambda dt: self.update(), 5)
|
Clock.schedule_interval(lambda dt: self.update(), 5)
|
||||||
|
|
||||||
def expiry(self):
|
def expiry(self):
|
||||||
|
@ -440,10 +417,6 @@ class ReceiveScreen(CScreen):
|
||||||
amount = Decimal(a) * pow(10, self.app.decimal_point())
|
amount = Decimal(a) * pow(10, self.app.decimal_point())
|
||||||
return create_bip21_uri(self.screen.address, amount, self.screen.message)
|
return create_bip21_uri(self.screen.address, amount, self.screen.message)
|
||||||
|
|
||||||
def do_share(self):
|
|
||||||
uri = self.get_URI()
|
|
||||||
self.app.do_share(uri, _("Share Bitcoin Request"))
|
|
||||||
|
|
||||||
def do_copy(self):
|
def do_copy(self):
|
||||||
uri = self.get_URI()
|
uri = self.get_URI()
|
||||||
self.app._clipboard.copy(uri)
|
self.app._clipboard.copy(uri)
|
||||||
|
@ -498,8 +471,7 @@ class ReceiveScreen(CScreen):
|
||||||
requests_container = self.screen.ids.requests_container
|
requests_container = self.screen.ids.requests_container
|
||||||
requests_container.data = [self.get_card(item) for item in _list if item.get('status') != PR_PAID]
|
requests_container.data = [self.get_card(item) for item in _list if item.get('status') != PR_PAID]
|
||||||
|
|
||||||
def do_show(self, obj):
|
def show_item(self, obj):
|
||||||
self.hide_menu()
|
|
||||||
self.app.show_request(obj.is_lightning, obj.key)
|
self.app.show_request(obj.is_lightning, obj.key)
|
||||||
|
|
||||||
def expiration_dialog(self, obj):
|
def expiration_dialog(self, obj):
|
||||||
|
@ -523,24 +495,7 @@ class ReceiveScreen(CScreen):
|
||||||
d = Question(_('Delete expired requests?'), callback)
|
d = Question(_('Delete expired requests?'), callback)
|
||||||
d.open()
|
d.open()
|
||||||
|
|
||||||
def delete_request_dialog(self, req):
|
|
||||||
def cb(result):
|
|
||||||
if result:
|
|
||||||
self.app.wallet.delete_request(req.key)
|
|
||||||
self.hide_menu()
|
|
||||||
self.update()
|
|
||||||
d = Question(_('Delete request?'), cb)
|
|
||||||
d.open()
|
|
||||||
|
|
||||||
def show_menu(self, obj):
|
|
||||||
self.hide_menu()
|
|
||||||
self.context_menu = ContextMenu(obj, self.menu_actions)
|
|
||||||
self.add_widget(self.context_menu)
|
|
||||||
|
|
||||||
def hide_menu(self):
|
|
||||||
if self.context_menu is not None:
|
|
||||||
self.remove_widget(self.context_menu)
|
|
||||||
self.context_menu = None
|
|
||||||
|
|
||||||
class TabbedCarousel(Factory.TabbedPanel):
|
class TabbedCarousel(Factory.TabbedPanel):
|
||||||
'''Custom TabbedPanel using a carousel used in the Main Screen
|
'''Custom TabbedPanel using a carousel used in the Main Screen
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
#:import Decimal decimal.Decimal
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Popup:
|
|
||||||
id: popup
|
|
||||||
is_invoice: True
|
|
||||||
amount: 0
|
|
||||||
requestor: ''
|
|
||||||
exp: ''
|
|
||||||
description: ''
|
|
||||||
status: ''
|
|
||||||
signature: ''
|
|
||||||
isaddr: ''
|
|
||||||
fund: 0
|
|
||||||
pk: ''
|
|
||||||
title: _('Invoice') if popup.is_invoice else _('Request')
|
|
||||||
tx_hash: ''
|
|
||||||
BoxLayout:
|
|
||||||
orientation: 'vertical'
|
|
||||||
ScrollView:
|
|
||||||
GridLayout:
|
|
||||||
cols: 1
|
|
||||||
height: self.minimum_height
|
|
||||||
size_hint_y: None
|
|
||||||
padding: '10dp'
|
|
||||||
spacing: '10dp'
|
|
||||||
GridLayout:
|
|
||||||
cols: 1
|
|
||||||
size_hint_y: None
|
|
||||||
height: self.minimum_height
|
|
||||||
spacing: '10dp'
|
|
||||||
BoxLabel:
|
|
||||||
text: (_('Status') if popup.amount or popup.is_invoice or popup.isaddr == 'y' else _('Amount received')) if root.status else ''
|
|
||||||
value: root.status
|
|
||||||
BoxLabel:
|
|
||||||
text: _('Request amount') if root.amount else ''
|
|
||||||
value: app.format_amount_and_units(root.amount) if root.amount else ''
|
|
||||||
BoxLabel:
|
|
||||||
text: _('Requestor') if popup.is_invoice else _('Address')
|
|
||||||
value: root.requestor
|
|
||||||
BoxLabel:
|
|
||||||
text: _('Signature') if root.signature else ''
|
|
||||||
value: root.signature
|
|
||||||
BoxLabel:
|
|
||||||
text: _('Expiration') if root.exp else ''
|
|
||||||
value: root.exp
|
|
||||||
BoxLabel:
|
|
||||||
text: _('Description') if root.description else ''
|
|
||||||
value: root.description
|
|
||||||
BoxLabel:
|
|
||||||
text: _('Balance') if popup.fund else ''
|
|
||||||
value: app.format_amount_and_units(root.fund) if root.fund else ''
|
|
||||||
TopLabel:
|
|
||||||
text: _('Private Key')
|
|
||||||
RefLabel:
|
|
||||||
id: pk_label
|
|
||||||
touched: True if not self.touched else True
|
|
||||||
data: root.pk
|
|
||||||
|
|
||||||
TopLabel:
|
|
||||||
text: _('Outputs') if popup.is_invoice else ''
|
|
||||||
OutputList:
|
|
||||||
id: output_list
|
|
||||||
TopLabel:
|
|
||||||
text: _('Transaction ID') if popup.tx_hash else ''
|
|
||||||
TxHashLabel:
|
|
||||||
data: popup.tx_hash
|
|
||||||
name: _('Transaction ID')
|
|
||||||
Widget:
|
|
||||||
size_hint: 1, 0.1
|
|
||||||
|
|
||||||
BoxLayout:
|
|
||||||
size_hint: 1, None
|
|
||||||
height: '48dp'
|
|
||||||
Widget:
|
|
||||||
size_hint: 0.5, None
|
|
||||||
height: '48dp'
|
|
||||||
Button:
|
|
||||||
size_hint: 2, None
|
|
||||||
height: '48dp'
|
|
||||||
text: _('Close')
|
|
||||||
on_release: popup.dismiss()
|
|
||||||
Button:
|
|
||||||
size_hint: 2, None
|
|
||||||
height: '48dp'
|
|
||||||
text: _('Hide private key') if pk_label.data else _('Export private key')
|
|
||||||
on_release:
|
|
||||||
setattr(pk_label, 'data', '') if pk_label.data else popup.export(pk_label, popup.requestor)
|
|
Loading…
Add table
Reference in a new issue