kivy: store contacts as invoices

This commit is contained in:
ThomasV 2016-02-09 12:48:25 +01:00
parent f5fcae7f11
commit 078cabd745
6 changed files with 51 additions and 70 deletions

View File

@ -258,8 +258,8 @@ class ElectrumWindow(App):
panel.switch_to(tab) panel.switch_to(tab)
def show_request(self, addr): def show_request(self, addr):
self.receive_screen.screen.address = addr
self.switch_to('receive') self.switch_to('receive')
self.receive_screen.screen.address = addr
def scan_qr(self, on_complete): def scan_qr(self, on_complete):
if platform != 'android': if platform != 'android':

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 B

View File

@ -202,12 +202,32 @@ class SendScreen(CScreen):
self.screen.amount = self.app.format_amount_and_units(amount) self.screen.amount = self.app.format_amount_and_units(amount)
self.screen.message = pr.get_memo() self.screen.message = pr.get_memo()
def do_save(self):
if not self.screen.address:
return
if self.payment_request:
# it sould be already saved
return
# save address as invoice
from electrum.paymentrequest import make_unsigned_request, PaymentRequest
req = {'address':self.screen.address, 'memo':self.screen.message}
amount = self.app.get_amount(self.screen.amount) if self.screen.amount else 0
req['amount'] = amount
pr = make_unsigned_request(req).SerializeToString()
pr = PaymentRequest(pr)
self.app.invoices.add(pr)
self.app.update_tab('invoices')
self.app.show_info(_("Invoice saved"))
def do_paste(self): def do_paste(self):
contents = unicode(self.app._clipboard.paste()) contents = unicode(self.app._clipboard.paste())
if not contents:
self.app.show_info(_("Clipboard is empty"))
return
try: try:
uri = parse_URI(contents) uri = parse_URI(contents)
except: except:
self.app.show_info("Invalid URI", contents) self.app.show_info(_("Clipboard content is not a Bitcoin URI"))
return return
self.set_URI(uri) self.set_URI(uri)
@ -324,20 +344,14 @@ class ReceiveScreen(CScreen):
self.app._clipboard.copy(uri) self.app._clipboard.copy(uri)
self.app.show_info(_('Request copied to clipboard')) self.app.show_info(_('Request copied to clipboard'))
def do_save(self): def on_amount_or_message(self):
addr = str(self.screen.address) addr = str(self.screen.address)
amount = str(self.screen.amount) amount = str(self.screen.amount)
message = str(self.screen.message) #.ids.message_input.text) message = str(self.screen.message) #.ids.message_input.text)
if not message and not amount:
return False
amount = self.app.get_amount(amount) if amount else 0 amount = self.app.get_amount(amount) if amount else 0
req = self.app.wallet.make_payment_request(addr, amount, message, None) req = self.app.wallet.make_payment_request(addr, amount, message, None)
self.app.wallet.add_payment_request(req, self.app.electrum_config) self.app.wallet.add_payment_request(req, self.app.electrum_config)
self.app.update_tab('requests') self.app.update_tab('requests')
return True
def on_amount_or_message(self):
self.do_save()
Clock.schedule_once(lambda dt: self.update_qr()) Clock.schedule_once(lambda dt: self.update_qr())
def do_new(self): def do_new(self):
@ -345,34 +359,6 @@ class ReceiveScreen(CScreen):
self.app.show_info(_('Please use the existing requests first.')) self.app.show_info(_('Please use the existing requests first.'))
class ContactsScreen(CScreen):
kvname = 'contacts'
def add_new_contact(self):
dlg = Cache.get('electrum_widgets', 'NewContactDialog')
if not dlg:
dlg = NewContactDialog()
Cache.append('electrum_widgets', 'NewContactDialog', dlg)
dlg.open()
def update(self):
contact_list = self.screen.ids.contact_container
contact_list.clear_widgets()
child = -1
children = contact_list.children
for key in sorted(self.app.contacts.keys()):
_type, value = self.app.contacts[key]
child += 1
try:
if children[child].label == value:
continue
except IndexError:
pass
ci = Factory.ContactItem()
ci.address = key
ci.label = value
contact_list.add_widget(ci)
pr_text = { pr_text = {
PR_UNPAID:_('Pending'), PR_UNPAID:_('Pending'),
@ -401,11 +387,16 @@ class InvoicesScreen(CScreen):
ci = Factory.InvoiceItem() ci = Factory.InvoiceItem()
ci.key = pr.get_id() ci.key = pr.get_id()
ci.requestor = pr.get_requestor() ci.requestor = pr.get_requestor()
ci.memo = pr.memo ci.memo = pr.get_memo()
ci.amount = self.app.format_amount_and_units(pr.get_amount()) amount = pr.get_amount()
status = self.app.invoices.get_status(ci.key) if amount:
ci.status = pr_text[status] ci.amount = self.app.format_amount_and_units(amount)
ci.icon = pr_icon[status] status = self.app.invoices.get_status(ci.key)
ci.status = pr_text[status]
ci.icon = pr_icon[status]
else:
ci.amount = _('No Amount')
ci.status = ''
exp = pr.get_expiration_date() exp = pr.get_expiration_date()
ci.date = format_time(exp) if exp else _('Never') ci.date = format_time(exp) if exp else _('Never')
ci.screen = self ci.screen = self
@ -444,8 +435,9 @@ class RequestsScreen(CScreen):
expiration = req.get('exp', None) expiration = req.get('exp', None)
status = req.get('status') status = req.get('status')
signature = req.get('sig') signature = req.get('sig')
ci = Factory.RequestItem() ci = Factory.RequestItem()
ci.address = req['address'] ci.address = address
ci.memo = self.app.wallet.get_label(address) ci.memo = self.app.wallet.get_label(address)
if amount: if amount:
status = req.get('status') status = req.get('status')
@ -476,22 +468,6 @@ class RequestsScreen(CScreen):
d.open() d.open()
class CSpinner(Factory.Spinner):
'''CustomDropDown that allows fading out the dropdown
'''
def _update_dropdown(self, *largs):
dp = self._dropdown
cls = self.option_cls
if isinstance(cls, string_types):
cls = Factory.get(cls)
dp.clear_widgets()
def do_release(option):
Clock.schedule_once(lambda dt: dp.select(option.text), .25)
for value in self.values:
item = cls(text=value)
item.bind(on_release=do_release)
dp.add_widget(item)
class TabbedCarousel(Factory.TabbedPanel): class TabbedCarousel(Factory.TabbedPanel):

View File

@ -75,27 +75,27 @@ SendScreen:
height: '48dp' height: '48dp'
IconButton: IconButton:
id: qr id: qr
size_hint: 0.5, 1 size_hint: 0.6, 1
on_release: app.scan_qr(on_complete=app.set_URI) on_release: app.scan_qr(on_complete=app.set_URI)
icon: 'atlas://gui/kivy/theming/light/camera' icon: 'atlas://gui/kivy/theming/light/camera'
Button: Button:
id: paste_button
text: _('Paste') text: _('Paste')
on_release: s.parent.do_paste() on_release: s.parent.do_paste()
Button: Button:
text: _('Clear') text: _('Clear')
size_hint: 1, None
height: '48dp'
on_release: s.parent.do_clear() on_release: s.parent.do_clear()
IconButton:
size_hint: 0.6, 1
on_release: s.parent.do_save()
icon: 'atlas://gui/kivy/theming/light/save'
BoxLayout: BoxLayout:
size_hint: 1, None size_hint: 1, None
height: '48dp' height: '48dp'
Widget: Widget:
size_hint: 1, 1 size_hint: 2, 1
Button: Button:
text: _('Send') text: _('Pay')
size_hint: 1, None size_hint: 1, 1
height: '48dp'
on_release: s.parent.do_send() on_release: s.parent.do_send()
Widget: Widget:
size_hint: 1, 1 size_hint: 1, 1

View File

@ -186,8 +186,13 @@ class PaymentRequest:
def get_amount(self): def get_amount(self):
return sum(map(lambda x:x[2], self.outputs)) return sum(map(lambda x:x[2], self.outputs))
def get_address(self):
o = self.outputs[0]
assert o[0] == TYPE_ADDRESS
return o[1]
def get_requestor(self): def get_requestor(self):
return self.requestor if self.requestor else 'unknown' return self.requestor if self.requestor else self.get_address()
def get_verify_status(self): def get_verify_status(self):
return self.error return self.error
@ -196,7 +201,7 @@ class PaymentRequest:
return self.memo return self.memo
def get_id(self): def get_id(self):
return self.id return self.id if self.requestor else self.get_address()
def get_outputs(self): def get_outputs(self):
return self.outputs[:] return self.outputs[:]
@ -421,7 +426,7 @@ class InvoiceStore(object):
for k, pr in self.invoices.items(): for k, pr in self.invoices.items():
l[k] = { l[k] = {
'hex': str(pr).encode('hex'), 'hex': str(pr).encode('hex'),
'requestor': pr.get_requestor(), 'requestor': pr.requestor,
'txid': pr.tx 'txid': pr.tx
} }
path = os.path.join(self.config.path, 'invoices') path = os.path.join(self.config.path, 'invoices')