mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
Kivy: Lightning support in Receive tab
This commit is contained in:
parent
c64c9b5d0b
commit
f6ee7adabd
9 changed files with 439 additions and 20 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -19,8 +19,12 @@ bin/
|
||||||
# icons
|
# icons
|
||||||
electrum/gui/qt/icons_rc.py
|
electrum/gui/qt/icons_rc.py
|
||||||
electrum/gui/kivy/theming/light-0.png
|
electrum/gui/kivy/theming/light-0.png
|
||||||
|
electrum/gui/kivy/theming/light-1.png
|
||||||
electrum/gui/kivy/theming/light.atlas
|
electrum/gui/kivy/theming/light.atlas
|
||||||
electrum/gui/kivy/theming/light/network.png
|
electrum/gui/kivy/theming/light/network.png
|
||||||
|
electrum/gui/kivy/theming/light/lightning_switch_off.png
|
||||||
|
electrum/gui/kivy/theming/light/lightning_switch_on.png
|
||||||
|
electrum/gui/kivy/theming/light/lightning.png
|
||||||
|
|
||||||
# tests/tox
|
# tests/tox
|
||||||
.tox/
|
.tox/
|
||||||
|
|
|
@ -5,7 +5,9 @@ PYTHON = python3
|
||||||
.PHONY: theming apk clean
|
.PHONY: theming apk clean
|
||||||
|
|
||||||
theming:
|
theming:
|
||||||
bash -c "convert -background none theming/light/network.{svg,png}"
|
bash -c 'for i in network lightning; do convert -background none theming/light/$$i.{svg,png}; done'
|
||||||
|
convert -background none -crop +0+390 theming/light/lightning_switch.svg theming/light/lightning_switch_off.png
|
||||||
|
convert -background none -crop 840x390+0+0 theming/light/lightning_switch.svg theming/light/lightning_switch_on.png
|
||||||
$(PYTHON) -m kivy.atlas theming/light 1024 theming/light/*.png
|
$(PYTHON) -m kivy.atlas theming/light 1024 theming/light/*.png
|
||||||
prepare:
|
prepare:
|
||||||
# running pre build setup
|
# running pre build setup
|
||||||
|
|
|
@ -959,6 +959,15 @@ 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):
|
def invoices_dialog(self, screen):
|
||||||
from .uix.dialogs.invoices import InvoicesDialog
|
from .uix.dialogs.invoices import InvoicesDialog
|
||||||
if len(self.wallet.invoices.sorted_list()) == 0:
|
if len(self.wallet.invoices.sorted_list()) == 0:
|
||||||
|
|
6
electrum/gui/kivy/theming/light/lightning.svg
Normal file
6
electrum/gui/kivy/theming/light/lightning.svg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="210.01" height="258.6" version="1.1" viewBox="0 0 55.564 68.421" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g transform="translate(-37.066 -74.368)">
|
||||||
|
<path d="m38.127 110.58 40.719-34.163c1.8833-1.4037 4.6684-4.2048 2.3466 0.82819l-13.527 25.467 23.12 0.34508c1.0576 0.11762 2.8154-0.14879 1.1733 1.4493l-40.582 35.474c-2.6048 2.0742-6.2555 5.6722-2.6916-1.2423l13.251-25.398-22.913-0.55213c-2.1564 0.0996-2.6432-0.5521-0.8972-2.2085z" fill="#fff" fill-rule="evenodd" stroke-width=".13606"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 553 B |
288
electrum/gui/kivy/theming/light/lightning_switch.svg
Normal file
288
electrum/gui/kivy/theming/light/lightning_switch.svg
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="840"
|
||||||
|
height="820.04102"
|
||||||
|
viewBox="0 0 222.25 216.96919"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||||
|
sodipodi:docname="lightning_switch.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1019">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#6464f6;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop1015" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#76acff;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop1017" />
|
||||||
|
</linearGradient>
|
||||||
|
<filter
|
||||||
|
inkscape:collect="always"
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
id="filter2183"
|
||||||
|
x="-0.023532996"
|
||||||
|
width="1.047066"
|
||||||
|
y="-0.030062485"
|
||||||
|
height="1.060125">
|
||||||
|
<feGaussianBlur
|
||||||
|
inkscape:collect="always"
|
||||||
|
stdDeviation="0.92777831"
|
||||||
|
id="feGaussianBlur2185" />
|
||||||
|
</filter>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient980"
|
||||||
|
x1="94.415001"
|
||||||
|
x2="166.42999"
|
||||||
|
y1="48.271999"
|
||||||
|
y2="-6.3376999"
|
||||||
|
gradientTransform="matrix(0.90487595,0,0,0.90487595,-32.116675,75.52401)"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop
|
||||||
|
id="stop973"
|
||||||
|
stop-color="#fff"
|
||||||
|
offset="0" />
|
||||||
|
<stop
|
||||||
|
id="stop975"
|
||||||
|
stop-color="#fff"
|
||||||
|
stop-opacity="0"
|
||||||
|
offset="1" />
|
||||||
|
</linearGradient>
|
||||||
|
<filter
|
||||||
|
inkscape:collect="always"
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
id="filter3047"
|
||||||
|
x="-0.055550463"
|
||||||
|
width="1.1111009"
|
||||||
|
y="-0.068128757"
|
||||||
|
height="1.1362575">
|
||||||
|
<feGaussianBlur
|
||||||
|
inkscape:collect="always"
|
||||||
|
stdDeviation="2.1025669"
|
||||||
|
id="feGaussianBlur3049" />
|
||||||
|
</filter>
|
||||||
|
<filter
|
||||||
|
inkscape:collect="always"
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
id="filter3047-6"
|
||||||
|
x="-0.055550463"
|
||||||
|
width="1.1111009"
|
||||||
|
y="-0.068128757"
|
||||||
|
height="1.1362575">
|
||||||
|
<feGaussianBlur
|
||||||
|
inkscape:collect="always"
|
||||||
|
stdDeviation="2.1025669"
|
||||||
|
id="feGaussianBlur3049-1" />
|
||||||
|
</filter>
|
||||||
|
<filter
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
inkscape:label="Color Shift"
|
||||||
|
id="filter3759">
|
||||||
|
<feColorMatrix
|
||||||
|
type="hueRotate"
|
||||||
|
values="330"
|
||||||
|
result="color1"
|
||||||
|
id="feColorMatrix3755" />
|
||||||
|
<feColorMatrix
|
||||||
|
type="saturate"
|
||||||
|
values="0"
|
||||||
|
result="color2"
|
||||||
|
id="feColorMatrix3757" />
|
||||||
|
</filter>
|
||||||
|
<filter
|
||||||
|
inkscape:collect="always"
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
id="filter7464"
|
||||||
|
x="-0.085763194"
|
||||||
|
width="1.1715264"
|
||||||
|
y="-0.19973423"
|
||||||
|
height="1.3994684">
|
||||||
|
<feGaussianBlur
|
||||||
|
inkscape:collect="always"
|
||||||
|
stdDeviation="6.6951018"
|
||||||
|
id="feGaussianBlur7466" />
|
||||||
|
</filter>
|
||||||
|
<filter
|
||||||
|
inkscape:collect="always"
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
id="filter7532"
|
||||||
|
x="-0.042373311"
|
||||||
|
width="1.0847466"
|
||||||
|
y="-0.098647438"
|
||||||
|
height="1.197295">
|
||||||
|
<feGaussianBlur
|
||||||
|
inkscape:collect="always"
|
||||||
|
stdDeviation="3.3066669"
|
||||||
|
id="feGaussianBlur7534" />
|
||||||
|
</filter>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1019"
|
||||||
|
id="linearGradient861"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="68.955536"
|
||||||
|
y1="108.44135"
|
||||||
|
x2="68.688263"
|
||||||
|
y2="66.212761" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient980"
|
||||||
|
id="linearGradient863"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.90487595,0,0,0.90487595,-32.116675,75.52401)"
|
||||||
|
x1="94.415001"
|
||||||
|
y1="48.271999"
|
||||||
|
x2="166.42999"
|
||||||
|
y2="-6.3376999" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#000000"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1"
|
||||||
|
inkscape:cx="256.4408"
|
||||||
|
inkscape:cy="683.69642"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:lockguides="true"
|
||||||
|
inkscape:window-width="3066"
|
||||||
|
inkscape:window-height="1689"
|
||||||
|
inkscape:window-x="134"
|
||||||
|
inkscape:window-y="55"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
units="px"
|
||||||
|
inkscape:pagecheckerboard="false" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-5.9067634,-55.147908)"
|
||||||
|
style="display:inline">
|
||||||
|
<use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#g6758"
|
||||||
|
id="use6798"
|
||||||
|
transform="translate(0,108.47917)"
|
||||||
|
width="100%"
|
||||||
|
height="100%" />
|
||||||
|
<g
|
||||||
|
id="g6758"
|
||||||
|
transform="matrix(1.0279896,0,0,1,-0.39555549,0)">
|
||||||
|
<rect
|
||||||
|
y="68.48455"
|
||||||
|
x="19.243406"
|
||||||
|
height="80.448128"
|
||||||
|
width="187.35594"
|
||||||
|
id="rect815"
|
||||||
|
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#646464;fill-opacity:1;stroke:#555555;stroke-width:5;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path817"
|
||||||
|
d="M 19.243406,68.484551 H 206.59935 V 148.93268 H 19.243406 Z"
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter7464)" />
|
||||||
|
<path
|
||||||
|
transform="matrix(1.0553762,0,0,1.123304,-2.8259824,-10.045808)"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path817-5"
|
||||||
|
d="M 16.068404,65.838715 H 203.35612 V 146.28683 H 16.068404 Z"
|
||||||
|
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:11.48041821;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.19002374;filter:url(#filter7532)"
|
||||||
|
sodipodi:nodetypes="ccccc" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3255">
|
||||||
|
<rect
|
||||||
|
y="71.281387"
|
||||||
|
x="21.910538"
|
||||||
|
height="74.067993"
|
||||||
|
width="90.839211"
|
||||||
|
id="rect1013"
|
||||||
|
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient861);fill-opacity:1;stroke:none;stroke-width:5;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;filter:url(#filter2183);enable-background:accumulate" />
|
||||||
|
<path
|
||||||
|
d="M 38.12696,110.58365 78.846174,76.421035 c 1.883303,-1.403703 4.668394,-4.204849 2.34658,0.828194 l -13.527082,25.467191 23.120205,0.34508 c 1.057575,0.11762 2.815437,-0.14879 1.173278,1.44929 L 51.377359,139.985 c -2.604817,2.07419 -6.255505,5.67223 -2.69162,-1.2423 l 13.251022,-25.39781 -22.913402,-0.55213 c -2.156371,0.0996 -2.643184,-0.5521 -0.897201,-2.20849 z"
|
||||||
|
id="path817-3"
|
||||||
|
style="fill:url(#linearGradient863);fill-rule:evenodd;stroke-width:0.13605724"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<g
|
||||||
|
transform="rotate(180,67.330143,108.31538)"
|
||||||
|
id="g3148">
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#000976;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3047)"
|
||||||
|
d="M 112.74975,71.281387 V 145.34938 H 21.910537"
|
||||||
|
id="path2289"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="rotate(-180,67.330143,108.31538)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#91c5ff;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.50831353;filter:url(#filter3047-6)"
|
||||||
|
d="M 112.74975,71.281389 V 145.34938 H 21.910538"
|
||||||
|
id="path2289-8"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:37.21456909px;line-height:100%;font-family:FreeSans;-inkscape-font-specification:'Sans Bold';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.48097134px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
x="163.34431"
|
||||||
|
y="121.71754"
|
||||||
|
id="text3053"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3051"
|
||||||
|
x="163.34431"
|
||||||
|
y="121.71754"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke-width:2.48097134px">ON</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:37.21456909px;line-height:100%;font-family:FreeSans;-inkscape-font-specification:'Sans Bold';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.48097134px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
x="70.730072"
|
||||||
|
y="229.30695"
|
||||||
|
id="text3053-9"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3051-3"
|
||||||
|
x="70.730072"
|
||||||
|
y="229.30695"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke-width:2.48097134px">OFF</tspan></text>
|
||||||
|
<use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#g3255"
|
||||||
|
id="use3263"
|
||||||
|
transform="translate(96.165992,108.52486)"
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
style="filter:url(#filter3759)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 10 KiB |
65
electrum/gui/kivy/uix/dialogs/lightning_invoices.py
Normal file
65
electrum/gui/kivy/uix/dialogs/lightning_invoices.py
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
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
|
|
@ -15,6 +15,8 @@ from kivy.properties import (ObjectProperty, DictProperty, NumericProperty,
|
||||||
|
|
||||||
from kivy.uix.recycleview import RecycleView
|
from kivy.uix.recycleview import RecycleView
|
||||||
from kivy.uix.label import Label
|
from kivy.uix.label import Label
|
||||||
|
from kivy.uix.behaviors import ToggleButtonBehavior
|
||||||
|
from kivy.uix.image import Image
|
||||||
|
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.factory import Factory
|
from kivy.factory import Factory
|
||||||
|
@ -385,6 +387,7 @@ class ReceiveScreen(CScreen):
|
||||||
self.screen.address = ''
|
self.screen.address = ''
|
||||||
self.screen.amount = ''
|
self.screen.amount = ''
|
||||||
self.screen.message = ''
|
self.screen.message = ''
|
||||||
|
self.screen.lnaddr = ''
|
||||||
|
|
||||||
def get_new_address(self):
|
def get_new_address(self):
|
||||||
if not self.app.wallet:
|
if not self.app.wallet:
|
||||||
|
@ -421,18 +424,30 @@ class ReceiveScreen(CScreen):
|
||||||
|
|
||||||
@profiler
|
@profiler
|
||||||
def update_qr(self):
|
def update_qr(self):
|
||||||
uri = self.get_URI()
|
|
||||||
qr = self.screen.ids.qr
|
qr = self.screen.ids.qr
|
||||||
qr.set_data(uri)
|
if self.screen.ids.lnbutton.state == 'down':
|
||||||
|
qr.set_data(self.screen.lnaddr)
|
||||||
|
else:
|
||||||
|
uri = self.get_URI()
|
||||||
|
qr.set_data(uri)
|
||||||
|
|
||||||
def do_share(self):
|
def do_share(self):
|
||||||
uri = self.get_URI()
|
if self.screen.ids.lnbutton.state == 'down':
|
||||||
self.app.do_share(uri, _("Share Bitcoin Request"))
|
if self.screen.lnaddr:
|
||||||
|
self.app.do_share('lightning://' + self.lnaddr, _('Share Lightning invoice'))
|
||||||
|
else:
|
||||||
|
uri = self.get_URI()
|
||||||
|
self.app.do_share(uri, _("Share Bitcoin Request"))
|
||||||
|
|
||||||
def do_copy(self):
|
def do_copy(self):
|
||||||
uri = self.get_URI()
|
if self.screen.ids.lnbutton.state == 'down':
|
||||||
self.app._clipboard.copy(uri)
|
if self.screen.lnaddr:
|
||||||
self.app.show_info(_('Request copied to clipboard'))
|
self.app._clipboard.copy(self.screen.lnaddr)
|
||||||
|
self.app.show_info(_('Invoice copied to clipboard'))
|
||||||
|
else:
|
||||||
|
uri = self.get_URI()
|
||||||
|
self.app._clipboard.copy(uri)
|
||||||
|
self.app.show_info(_('Request copied to clipboard'))
|
||||||
|
|
||||||
def save_request(self):
|
def save_request(self):
|
||||||
addr = self.screen.address
|
addr = self.screen.address
|
||||||
|
@ -453,6 +468,9 @@ class ReceiveScreen(CScreen):
|
||||||
return added_request
|
return added_request
|
||||||
|
|
||||||
def on_amount_or_message(self):
|
def on_amount_or_message(self):
|
||||||
|
if self.screen.ids.lnbutton.state == 'down':
|
||||||
|
if self.screen.amount:
|
||||||
|
self.screen.lnaddr = self.app.wallet.lnworker.add_invoice(self.app.get_amount(self.screen.amount), self.screen.message)
|
||||||
Clock.schedule_once(lambda dt: self.update_qr())
|
Clock.schedule_once(lambda dt: self.update_qr())
|
||||||
|
|
||||||
def do_new(self):
|
def do_new(self):
|
||||||
|
@ -464,6 +482,13 @@ class ReceiveScreen(CScreen):
|
||||||
if self.save_request():
|
if self.save_request():
|
||||||
self.app.show_info(_('Request was saved.'))
|
self.app.show_info(_('Request was saved.'))
|
||||||
|
|
||||||
|
def do_open_lnaddr(self, lnaddr):
|
||||||
|
self.clear()
|
||||||
|
self.screen.lnaddr = lnaddr
|
||||||
|
obj = lndecode(lnaddr, expected_hrp=constants.net.SEGWIT_HRP)
|
||||||
|
self.screen.message = dict(obj.tags).get('d', '')
|
||||||
|
self.screen.amount = self.app.format_amount_and_units(int(obj.amount * bitcoin.COIN))
|
||||||
|
self.on_amount_or_message()
|
||||||
|
|
||||||
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
|
||||||
|
@ -537,3 +562,15 @@ class TabbedCarousel(Factory.TabbedPanel):
|
||||||
self.carousel.add_widget(widget)
|
self.carousel.add_widget(widget)
|
||||||
return
|
return
|
||||||
super(TabbedCarousel, self).add_widget(widget, index=index)
|
super(TabbedCarousel, self).add_widget(widget, index=index)
|
||||||
|
|
||||||
|
class LightningButton(ToggleButtonBehavior, Image):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.source = 'atlas://electrum/gui/kivy/theming/light/lightning_switch_off'
|
||||||
|
|
||||||
|
def on_state(self, widget, value):
|
||||||
|
self.state = value
|
||||||
|
if value == 'down':
|
||||||
|
self.source = 'atlas://electrum/gui/kivy/theming/light/lightning_switch_on'
|
||||||
|
else:
|
||||||
|
self.source = 'atlas://electrum/gui/kivy/theming/light/lightning_switch_off'
|
||||||
|
|
|
@ -14,6 +14,7 @@ ReceiveScreen:
|
||||||
amount: ''
|
amount: ''
|
||||||
message: ''
|
message: ''
|
||||||
status: ''
|
status: ''
|
||||||
|
lnaddr: ''
|
||||||
|
|
||||||
on_address:
|
on_address:
|
||||||
self.parent.on_address(self.address)
|
self.parent.on_address(self.address)
|
||||||
|
@ -30,6 +31,7 @@ ReceiveScreen:
|
||||||
FloatLayout:
|
FloatLayout:
|
||||||
id: bl
|
id: bl
|
||||||
QRCodeWidget:
|
QRCodeWidget:
|
||||||
|
opacity: 0 if lnbutton.state == 'down' and not s.lnaddr else 1
|
||||||
id: qr
|
id: qr
|
||||||
size_hint: None, 1
|
size_hint: None, 1
|
||||||
width: min(self.height, bl.width)
|
width: min(self.height, bl.width)
|
||||||
|
@ -62,15 +64,15 @@ ReceiveScreen:
|
||||||
height: blue_bottom.item_height
|
height: blue_bottom.item_height
|
||||||
spacing: '5dp'
|
spacing: '5dp'
|
||||||
Image:
|
Image:
|
||||||
source: 'atlas://electrum/gui/kivy/theming/light/globe'
|
source: 'atlas://electrum/gui/kivy/theming/light/lightning' if lnbutton.state == 'down' else 'atlas://electrum/gui/kivy/theming/light/globe'
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
size: '22dp', '22dp'
|
size: '22dp', '22dp'
|
||||||
pos_hint: {'center_y': .5}
|
pos_hint: {'center_y': .5}
|
||||||
BlueButton:
|
BlueButton:
|
||||||
id: address_label
|
id: address_label
|
||||||
text: s.address if s.address else _('Bitcoin Address')
|
text: (s.address if s.address else _('Bitcoin Address')) if lnbutton.state != 'down' else (s.lnaddr if s.lnaddr else _('Please enter amount'))
|
||||||
shorten: True
|
shorten: True
|
||||||
on_release: Clock.schedule_once(lambda dt: app.addresses_dialog(s))
|
on_release: Clock.schedule_once(lambda dt: app.addresses_dialog(s) if lnbutton.state != 'down' else s.parent.do_copy())
|
||||||
CardSeparator:
|
CardSeparator:
|
||||||
opacity: message_selection.opacity
|
opacity: message_selection.opacity
|
||||||
color: blue_bottom.foreground_color
|
color: blue_bottom.foreground_color
|
||||||
|
@ -111,15 +113,17 @@ ReceiveScreen:
|
||||||
size_hint: 1, None
|
size_hint: 1, None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
IconButton:
|
IconButton:
|
||||||
icon: 'atlas://electrum/gui/kivy/theming/light/save'
|
opacity: 1 if lnbutton.state != 'down' else 0
|
||||||
size_hint: 0.6, None
|
icon: 'atlas://electrum/gui/kivy/theming/light/save' if lnbutton.state != 'down' else ''
|
||||||
|
size_hint: (0 if lnbutton.state == 'down' else 0.6), None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
on_release: s.parent.do_save()
|
on_release: s.parent.do_save() if lnbutton.state != 'down' else None
|
||||||
|
width: (0 if lnbutton.state == 'down' else 100)
|
||||||
Button:
|
Button:
|
||||||
text: _('Requests')
|
text: _('Requests') if lnbutton.state != 'down' else _('Lightning Invoices')
|
||||||
size_hint: 1, None
|
size_hint: 1 + (.6 if lnbutton.state == 'down' else 0), None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
on_release: Clock.schedule_once(lambda dt: app.requests_dialog(s))
|
on_release: Clock.schedule_once(lambda dt: app.requests_dialog(s) if lnbutton.state != 'down' else app.lightning_invoices_dialog(s.parent.do_open_lnaddr))
|
||||||
Button:
|
Button:
|
||||||
text: _('Copy')
|
text: _('Copy')
|
||||||
size_hint: 1, None
|
size_hint: 1, None
|
||||||
|
@ -133,8 +137,11 @@ ReceiveScreen:
|
||||||
BoxLayout:
|
BoxLayout:
|
||||||
size_hint: 1, None
|
size_hint: 1, None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
|
LightningButton
|
||||||
|
id: lnbutton
|
||||||
|
on_state: s.parent.on_amount_or_message()
|
||||||
Widget
|
Widget
|
||||||
size_hint: 2, 1
|
size_hint: 1, 1
|
||||||
Button:
|
Button:
|
||||||
text: _('New')
|
text: _('New')
|
||||||
size_hint: 1, None
|
size_hint: 1, None
|
||||||
|
|
|
@ -115,7 +115,8 @@ class LNWorker(PrintError):
|
||||||
if report['unsettled']:
|
if report['unsettled']:
|
||||||
yield 'Your unsettled invoices:'
|
yield 'Your unsettled invoices:'
|
||||||
yield '------------------------'
|
yield '------------------------'
|
||||||
for addr, preimage in report['unsettled']:
|
for addr, preimage, pay_req in report['unsettled']:
|
||||||
|
yield pay_req
|
||||||
yield str(addr)
|
yield str(addr)
|
||||||
yield 'Preimage: ' + bh2u(preimage)
|
yield 'Preimage: ' + bh2u(preimage)
|
||||||
yield ''
|
yield ''
|
||||||
|
@ -143,7 +144,7 @@ class LNWorker(PrintError):
|
||||||
settled.append((datetime.fromtimestamp(date, timezone.utc), HTLCOwner(direction), htlcobj, preimage))
|
settled.append((datetime.fromtimestamp(date, timezone.utc), HTLCOwner(direction), htlcobj, preimage))
|
||||||
for preimage, pay_req in invoices.values():
|
for preimage, pay_req in invoices.values():
|
||||||
addr = lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP)
|
addr = lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP)
|
||||||
unsettled.append((addr, bfh(preimage)))
|
unsettled.append((addr, bfh(preimage), pay_req))
|
||||||
for pay_req, amount_sat in self.paying.values():
|
for pay_req, amount_sat in self.paying.values():
|
||||||
addr = lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP)
|
addr = lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP)
|
||||||
if amount_sat is not None:
|
if amount_sat is not None:
|
||||||
|
|
Loading…
Add table
Reference in a new issue