11 changed files with 208 additions and 603 deletions
@ -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() |
||||
@ -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 |
||||
@ -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 |
||||
@ -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…
Reference in new issue