mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-03 12:30:07 +00:00
kivy: show pending requests in receive tab instead of dialog
This commit is contained in:
parent
f8038d024b
commit
46c2d7821f
3 changed files with 141 additions and 195 deletions
|
@ -1,175 +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
|
||||
|
||||
from electrum.util import age, PR_UNPAID
|
||||
from electrum.lnutil import SENT, RECEIVED
|
||||
from electrum.lnaddr import lndecode
|
||||
import electrum.constants as constants
|
||||
from electrum.bitcoin import COIN
|
||||
|
||||
Builder.load_string('''
|
||||
<RequestLabel@Label>
|
||||
#color: .305, .309, .309, 1
|
||||
text_size: self.width, None
|
||||
halign: 'left'
|
||||
valign: 'top'
|
||||
|
||||
<RequestItem@CardItem>
|
||||
address: ''
|
||||
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
|
||||
RequestLabel:
|
||||
text: root.address
|
||||
shorten: True
|
||||
Widget
|
||||
RequestLabel:
|
||||
text: root.memo
|
||||
color: .699, .699, .699, 1
|
||||
font_size: '13sp'
|
||||
shorten: True
|
||||
Widget
|
||||
BoxLayout:
|
||||
spacing: '8dp'
|
||||
height: '32dp'
|
||||
orientation: 'vertical'
|
||||
Widget
|
||||
RequestLabel:
|
||||
text: root.amount
|
||||
halign: 'right'
|
||||
font_size: '15sp'
|
||||
Widget
|
||||
RequestLabel:
|
||||
text: root.status
|
||||
halign: 'right'
|
||||
font_size: '13sp'
|
||||
color: .699, .699, .699, 1
|
||||
Widget
|
||||
|
||||
<RequestsDialog@Popup>
|
||||
id: popup
|
||||
title: _('Pending requests')
|
||||
BoxLayout:
|
||||
id:box
|
||||
orientation: 'vertical'
|
||||
spacing: '1dp'
|
||||
ScrollView:
|
||||
GridLayout:
|
||||
cols: 1
|
||||
id: requests_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
|
||||
|
||||
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'
|
||||
}
|
||||
request_text = {
|
||||
PR_UNPAID: _('Pending'),
|
||||
PR_UNKNOWN: _('Unknown'),
|
||||
PR_PAID: _('Received'),
|
||||
PR_EXPIRED: _('Expired')
|
||||
}
|
||||
|
||||
|
||||
class RequestsDialog(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, is_lightning, key, address, amount, memo, timestamp):
|
||||
ci = self.cards.get(key)
|
||||
if ci is None:
|
||||
ci = Factory.RequestItem()
|
||||
ci.address = address
|
||||
ci.screen = self
|
||||
ci.is_lightning = is_lightning
|
||||
ci.key = key
|
||||
self.cards[key] = ci
|
||||
|
||||
ci.amount = self.app.format_amount_and_units(amount) if amount else ''
|
||||
ci.memo = memo
|
||||
ci.status = age(timestamp)
|
||||
#ci.icon = pr_icon[status]
|
||||
#exp = pr.get_expiration_date()
|
||||
#ci.date = format_time(exp) if exp else _('Never')
|
||||
return ci
|
||||
|
||||
def update(self):
|
||||
self.menu_actions = [(_('Show'), self.do_show), (_('Delete'), self.do_delete)]
|
||||
requests_list = self.ids.requests_container
|
||||
requests_list.clear_widgets()
|
||||
_list = self.app.wallet.get_sorted_requests(self.app.electrum_config)
|
||||
for req in _list[::-1]:
|
||||
is_lightning = req.get('lightning', False)
|
||||
status = req['status']
|
||||
if status != PR_UNPAID:
|
||||
continue
|
||||
if not is_lightning:
|
||||
address = req['address']
|
||||
key = address
|
||||
else:
|
||||
key = req['rhash']
|
||||
address = req['invoice']
|
||||
timestamp = req.get('time', 0)
|
||||
amount = req.get('amount')
|
||||
description = req.get('memo', '')
|
||||
ci = self.get_card(is_lightning, key, address, amount, description, timestamp)
|
||||
requests_list.add_widget(ci)
|
||||
|
||||
def do_show(self, obj):
|
||||
self.hide_menu()
|
||||
self.dismiss()
|
||||
self.app.show_request(obj.is_lightning, obj.key)
|
||||
|
||||
def do_delete(self, req):
|
||||
from .question import Question
|
||||
def cb(result):
|
||||
if result:
|
||||
self.app.wallet.remove_payment_request(req.address, self.app.electrum_config)
|
||||
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.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
|
|
@ -27,7 +27,7 @@ from electrum.util import profiler, parse_URI, format_time, InvalidPassword, Not
|
|||
from electrum import bitcoin, constants
|
||||
from electrum.transaction import TxOutput, Transaction, tx_from_str
|
||||
from electrum.util import send_exception_to_crash_reporter, parse_URI, InvalidBitcoinURI
|
||||
from electrum.util import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED, TxMinedInfo
|
||||
from electrum.util import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED, TxMinedInfo, age
|
||||
from electrum.plugin import run_hook
|
||||
from electrum.wallet import InternalAddressCorruption
|
||||
from electrum import simple_config
|
||||
|
@ -47,6 +47,9 @@ class Destination(Enum):
|
|||
class HistoryRecycleView(RecycleView):
|
||||
pass
|
||||
|
||||
class RequestRecycleView(RecycleView):
|
||||
pass
|
||||
|
||||
class CScreen(Factory.Screen):
|
||||
__events__ = ('on_activate', 'on_deactivate', 'on_enter', 'on_leave')
|
||||
action_view = ObjectProperty(None)
|
||||
|
@ -396,9 +399,15 @@ class SendScreen(CScreen):
|
|||
self.app.tx_dialog(tx)
|
||||
|
||||
|
||||
|
||||
class ReceiveScreen(CScreen):
|
||||
|
||||
kvname = 'receive'
|
||||
cards = {}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(ReceiveScreen, self).__init__(**kwargs)
|
||||
self.menu_actions = [(_('Show'), self.do_show), (_('Delete'), self.do_delete)]
|
||||
|
||||
def clear(self):
|
||||
self.screen.address = ''
|
||||
|
@ -454,11 +463,65 @@ class ReceiveScreen(CScreen):
|
|||
self.screen.address = addr
|
||||
req = self.app.wallet.make_payment_request(addr, amount, message, expiration)
|
||||
self.app.wallet.add_payment_request(req, self.app.electrum_config)
|
||||
#request = self.get_URI()
|
||||
key = addr
|
||||
self.app.show_request(lightning, key)
|
||||
|
||||
def get_card(self, req):
|
||||
is_lightning = req.get('lightning', False)
|
||||
status = req['status']
|
||||
#if status != PR_UNPAID:
|
||||
# continue
|
||||
if not is_lightning:
|
||||
address = req['address']
|
||||
key = address
|
||||
else:
|
||||
key = req['rhash']
|
||||
address = req['invoice']
|
||||
timestamp = req.get('time', 0)
|
||||
amount = req.get('amount')
|
||||
description = req.get('memo', '')
|
||||
ci = self.cards.get(key)
|
||||
if ci is None:
|
||||
ci = {}
|
||||
ci['address'] = address
|
||||
ci['is_lightning'] = is_lightning
|
||||
ci['key'] = key
|
||||
ci['screen'] = self
|
||||
self.cards[key] = ci
|
||||
ci['amount'] = self.app.format_amount_and_units(amount) if amount else ''
|
||||
ci['memo'] = description
|
||||
ci['status'] = age(timestamp)
|
||||
return ci
|
||||
|
||||
def update(self):
|
||||
self.menu_actions = [(_('Show'), self.do_show), (_('Delete'), self.do_delete)]
|
||||
_list = self.app.wallet.get_sorted_requests(self.app.electrum_config)
|
||||
requests_container = self.screen.ids.requests_container
|
||||
requests_container.data = [self.get_card(item) for item in _list]
|
||||
|
||||
def do_show(self, obj):
|
||||
self.hide_menu()
|
||||
self.app.show_request(obj.is_lightning, obj.key)
|
||||
|
||||
def do_delete(self, req):
|
||||
from .dialogs.question import Question
|
||||
def cb(result):
|
||||
if result:
|
||||
self.app.wallet.remove_payment_request(req.address, self.app.electrum_config)
|
||||
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):
|
||||
'''Custom TabbedPanel using a carousel used in the Main Screen
|
||||
|
|
|
@ -1,10 +1,71 @@
|
|||
#:import _ electrum.gui.kivy.i18n._
|
||||
#:import Factory kivy.factory.Factory
|
||||
#:import Decimal decimal.Decimal
|
||||
#:set btc_symbol chr(171)
|
||||
#:set mbtc_symbol chr(187)
|
||||
#:set font_light 'electrum/gui/kivy/data/fonts/Roboto-Condensed.ttf'
|
||||
|
||||
|
||||
<RequestLabel@Label>
|
||||
#color: .305, .309, .309, 1
|
||||
text_size: self.width, None
|
||||
halign: 'left'
|
||||
valign: 'top'
|
||||
|
||||
<RequestItem@CardItem>
|
||||
address: ''
|
||||
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
|
||||
RequestLabel:
|
||||
text: root.address
|
||||
shorten: True
|
||||
Widget
|
||||
RequestLabel:
|
||||
text: root.memo
|
||||
color: .699, .699, .699, 1
|
||||
font_size: '13sp'
|
||||
shorten: True
|
||||
Widget
|
||||
BoxLayout:
|
||||
spacing: '8dp'
|
||||
height: '32dp'
|
||||
orientation: 'vertical'
|
||||
Widget
|
||||
RequestLabel:
|
||||
text: root.amount
|
||||
halign: 'right'
|
||||
font_size: '15sp'
|
||||
Widget
|
||||
RequestLabel:
|
||||
text: root.status
|
||||
halign: 'right'
|
||||
font_size: '13sp'
|
||||
color: .699, .699, .699, 1
|
||||
Widget
|
||||
|
||||
<RequestRecycleView>:
|
||||
viewclass: 'RequestItem'
|
||||
RecycleBoxLayout:
|
||||
default_size: None, dp(56)
|
||||
default_size_hint: 1, None
|
||||
size_hint: 1, None
|
||||
height: self.minimum_height
|
||||
orientation: 'vertical'
|
||||
|
||||
|
||||
ReceiveScreen:
|
||||
id: s
|
||||
|
@ -14,6 +75,7 @@ ReceiveScreen:
|
|||
message: ''
|
||||
status: ''
|
||||
is_lightning: False
|
||||
show_list: True
|
||||
|
||||
BoxLayout
|
||||
padding: '12dp', '12dp', '12dp', '12dp'
|
||||
|
@ -29,7 +91,7 @@ ReceiveScreen:
|
|||
height: blue_bottom.item_height
|
||||
spacing: '5dp'
|
||||
Image:
|
||||
source: 'atlas://electrum/gui/kivy/theming/light/globe'
|
||||
source: 'atlas://electrum/gui/kivy/theming/light/lightning' if root.is_lightning else 'atlas://electrum/gui/kivy/theming/light/globe'
|
||||
size_hint: None, None
|
||||
size: '22dp', '22dp'
|
||||
pos_hint: {'center_y': .5}
|
||||
|
@ -37,9 +99,8 @@ ReceiveScreen:
|
|||
id: address_label
|
||||
text: _('Lightning') if root.is_lightning else (s.address if s.address else _('Bitcoin Address'))
|
||||
shorten: True
|
||||
on_release: root.is_lightning = not root.is_lightning
|
||||
#on_release: Clock.schedule_once(lambda dt: app.addresses_dialog(s))
|
||||
on_release:
|
||||
root.is_lightning = not root.is_lightning
|
||||
CardSeparator:
|
||||
opacity: message_selection.opacity
|
||||
color: blue_bottom.foreground_color
|
||||
|
@ -81,11 +142,12 @@ ReceiveScreen:
|
|||
height: '48dp'
|
||||
IconButton:
|
||||
icon: 'atlas://electrum/gui/kivy/theming/light/list'
|
||||
size_hint: 1, None
|
||||
size_hint: 0.5, None
|
||||
height: '48dp'
|
||||
on_release: Clock.schedule_once(lambda dt: app.requests_dialog(s))
|
||||
#Widget:
|
||||
# size_hint: 0.5, 1
|
||||
on_release: root.show_list = not root.show_list
|
||||
#Clock.schedule_once(lambda dt: app.requests_dialog(s))
|
||||
Widget:
|
||||
size_hint: 0.5, None
|
||||
Button:
|
||||
text: _('Clear')
|
||||
size_hint: 1, None
|
||||
|
@ -97,14 +159,10 @@ ReceiveScreen:
|
|||
height: '48dp'
|
||||
on_release: Clock.schedule_once(lambda dt: s.parent.new_request(root.is_lightning))
|
||||
Widget:
|
||||
size_hint: 1, 1
|
||||
#BoxLayout:
|
||||
# size_hint: 1, None
|
||||
# height: '48dp'
|
||||
# IconButton:
|
||||
# icon: 'atlas://electrum/gui/kivy/theming/light/list'
|
||||
# size_hint: 0.5, None
|
||||
# height: '48dp'
|
||||
# on_release: Clock.schedule_once(lambda dt: app.requests_dialog(s))
|
||||
# Widget:
|
||||
# size_hint: 2.5, 1
|
||||
size_hint: 1, 0.1
|
||||
RequestRecycleView:
|
||||
id: requests_container
|
||||
scroll_type: ['bars', 'content']
|
||||
bar_width: '25dp'
|
||||
opacity: 1 if root.show_list else 0
|
||||
disabled: not root.show_list
|
||||
|
|
Loading…
Add table
Reference in a new issue