the rest of the installation wizard +numerous small fixes

This commit is contained in:
qua-non 2014-02-20 00:24:37 +05:30 committed by ThomasV
parent 30126c544b
commit f185906950
10 changed files with 280 additions and 89 deletions

View File

@ -131,20 +131,24 @@ class InfoBubble(Bubble):
''' Allow bubble to be hidden on touch. ''' Allow bubble to be hidden on touch.
''' '''
exit = BooleanProperty(False)
''' exit app after bubble is closes
'''
dim_background = BooleanProperty(False) dim_background = BooleanProperty(False)
''' Whether to draw a background on the windows behind the bubble ''' Whether to draw a background on the windows behind the bubble
''' '''
def on_touch_down(self, touch): def on_touch_down(self, touch):
if self.modal: if self.modal:
return return True
self.hide() self.hide()
if self.collide_point(*touch.pos): if self.collide_point(*touch.pos):
return True return True
def show(self, pos, duration, width=None, modal=False): def show(self, pos, duration, width=None, modal=False, exit=False):
'''Animate the bubble into position''' '''Animate the bubble into position'''
self.modal = modal self.modal, self.exit = modal, exit
if width: if width:
self.width = width self.width = width
Window.add_widget(self) Window.add_widget(self)
@ -177,6 +181,11 @@ class InfoBubble(Bubble):
''' '''
def on_stop(*l): def on_stop(*l):
Window.remove_widget(self) Window.remove_widget(self)
if self.exit:
App.get_running_app().stop()
import sys
sys.exit()
anim = Animation(opacity=0, d=.25) anim = Animation(opacity=0, d=.25)
anim.bind(on_complete=on_stop) anim.bind(on_complete=on_stop)
anim.cancel_all(self) anim.cancel_all(self)
@ -412,6 +421,23 @@ class CreateAccountDialog(EventsDialog):
self.crcontent.add_widget(widget, index=index) self.crcontent.add_widget(widget, index=index)
class CreateRestoreDialog(CreateAccountDialog):
''' Initial Dialog for creating or restoring seed'''
def on_parent(self, instance, value):
if value:
self.ids.but_close.disabled = True
self.ids.but_close.opacity = 0
self._back = _back = partial(app.dispatch, 'on_back')
app.navigation_higherarchy.append(_back)
def close(self):
if self._back in app.navigation_higherarchy:
app.navigation_higherarchy.pop()
self._back = None
super(CreateRestoreDialog, self).close()
class InitSeedDialog(CreateAccountDialog): class InitSeedDialog(CreateAccountDialog):
seed_msg = StringProperty('') seed_msg = StringProperty('')
@ -436,30 +462,25 @@ class InitSeedDialog(CreateAccountDialog):
self._back = None self._back = None
super(InitSeedDialog, self).close() super(InitSeedDialog, self).close()
class CreateRestoreDialog(CreateAccountDialog):
''' Initial Dialog for creating or restoring seed'''
def on_parent(self, instance, value):
if value:
self.ids.but_close.disabled = True
self.ids.but_close.opacity = 0
self._back = _back = partial(app.dispatch, 'on_back')
app.navigation_higherarchy.append(_back)
def close(self):
if self._back in app.navigation_higherarchy:
app.navigation_higherarchy.pop()
self._back = None
super(CreateRestoreDialog, self).close()
class VerifySeedDialog(CreateAccountDialog): class VerifySeedDialog(CreateAccountDialog):
pass pass
class RestoreSeedDialog(CreateAccountDialog): class RestoreSeedDialog(CreateAccountDialog):
pass def on_parent(self, instance, value):
if value:
stepper = self.ids.stepper;
stepper.opacity = 1
stepper.source = 'atlas://gui/kivy/theming/light/stepper_restore_seed'
self._back = _back = partial(self.ids.back.dispatch, 'on_release')
app.navigation_higherarchy.append(_back)
def close(self):
if self._back in app.navigation_higherarchy:
app.navigation_higherarchy.pop()
self._back = None
super(RestoreSeedDialog, self).close()
class NewContactDialog(Popup): class NewContactDialog(Popup):
@ -508,11 +529,12 @@ class ChangePasswordDialog(CreateAccountDialog):
message = StringProperty(_('Empty Message')) message = StringProperty(_('Empty Message'))
'''Message to be displayed.''' '''Message to be displayed.'''
mode = OptionProperty('new', options=('new', 'confirm', 'create')) mode = OptionProperty('new',
options=('new', 'confirm', 'create', 'restore'))
''' Defines the mode of the password dialog.''' ''' Defines the mode of the password dialog.'''
def validate_new_password(self): def validate_new_password(self):
self.ids.confirm.dispatch('on_release') self.ids.next.dispatch('on_release')
def on_parent(self, instance, value): def on_parent(self, instance, value):
if value: if value:

View File

@ -31,7 +31,7 @@ class Drawer(StencilView):
and defaults to 200 (milliseconds) and defaults to 200 (milliseconds)
''' '''
scroll_distance = NumericProperty('4dp') scroll_distance = NumericProperty('9dp')
'''Distance to move before scrolling the :class:`Drawer` in pixels. '''Distance to move before scrolling the :class:`Drawer` in pixels.
As soon as the distance has been traveled, the :class:`Drawer` will As soon as the distance has been traveled, the :class:`Drawer` will
start to scroll, and no touch event will go to children. start to scroll, and no touch event will go to children.
@ -68,6 +68,11 @@ class Drawer(StencilView):
if self.disabled: if self.disabled:
return return
if not self.collide_point(*touch.pos):
return
touch.grab(self)
global app global app
if not app: if not app:
from kivy.app import App from kivy.app import App
@ -91,10 +96,9 @@ class Drawer(StencilView):
return return
def on_touch_move(self, touch): def on_touch_move(self, touch):
global app if not touch.grab_current:
if not app: return
from kivy.app import App
app = App.get_running_app()
# skip on tablet mode # skip on tablet mode
if app.ui_mode[0] == 't': if app.ui_mode[0] == 't':
return super(Drawer, self).on_touch_move(touch) return super(Drawer, self).on_touch_move(touch)
@ -124,6 +128,9 @@ class Drawer(StencilView):
return return
def on_touch_up(self, touch): def on_touch_up(self, touch):
if not touch.grab_current:
return
# skip on tablet mode # skip on tablet mode
if app.ui_mode[0] == 't': if app.ui_mode[0] == 't':
return super(Drawer, self).on_touch_down(touch) return super(Drawer, self).on_touch_down(touch)

View File

@ -1,14 +1,12 @@
from electrum import Wallet from electrum import Wallet
from electrum.i18n import _ from electrum.i18n import _
from electrum_gui.kivy.dialog import (CreateRestoreDialog, InitSeedDialog,
ChangePasswordDialog)
from kivy.app import App from kivy.app import App
from kivy.uix.widget import Widget from kivy.uix.widget import Widget
from kivy.core.window import Window from kivy.core.window import Window
from kivy.clock import Clock from kivy.clock import Clock
#from seed_dialog import SeedDialog from electrum_gui.kivy.dialog import CreateRestoreDialog
#from network_dialog import NetworkDialog #from network_dialog import NetworkDialog
#from util import * #from util import *
#from amountedit import AmountEdit #from amountedit import AmountEdit
@ -33,13 +31,18 @@ class InstallWizard(Widget):
def waiting_dialog(self, task, def waiting_dialog(self, task,
msg= _("Electrum is generating your addresses," msg= _("Electrum is generating your addresses,"
" please wait.")): " please wait."),
on_complete=None):
def target(): def target():
# run your threaded function
task() task()
# on completion hide message
Clock.schedule_once(lambda dt: Clock.schedule_once(lambda dt:
app.show_info_bubble(text="Complete", duration=.5, app.show_info_bubble(text="Complete", arrow_pos=None))
icon='atlas://gui/kivy/theming/light/important', # call completion routine
pos=Window.center, width='200dp', arrow_pos=None)) if on_complete:
Clock.schedule_once(lambda dt: on_complete())
app.show_info_bubble( app.show_info_bubble(
text=msg, icon='atlas://gui/kivy/theming/light/important', text=msg, icon='atlas://gui/kivy/theming/light/important',
@ -66,13 +69,58 @@ class InstallWizard(Widget):
self.change_password_dialog(wallet=wallet) self.change_password_dialog(wallet=wallet)
elif button == dialog.ids.restore: elif button == dialog.ids.restore:
# restore # restore
wallet.init_seed(None) self.restore_seed_dialog(wallet)
self.restore_seed_dialog()
#elif button == dialog.ids.watching: #elif button == dialog.ids.watching:
#TODO: not available in the new design
# self.action = 'watching' # self.action = 'watching'
else: else:
self.dispatch('on_wizard_complete', None) self.dispatch('on_wizard_complete', None)
def restore_seed_dialog(self, wallet):
from electrum_gui.kivy.dialog import RestoreSeedDialog
RestoreSeedDialog(
on_release=partial(self.on_verify_restore_ok, wallet)).open()
def on_verify_restore_ok(self, wallet, _dlg, btn, restore=False):
if _dlg.ids.back == btn:
_dlg.close()
CreateRestoreDialog(
on_release=self.on_creatrestore_complete).open()
return
seed = unicode(_dlg.ids.text_input_seed.text)
if not seed:
app.show_error(_("No seed!"))
return
try:
wallet.init_seed(seed)
except Exception:
import traceback
traceback.print_exc(file=sys.stdout)
app.show_error(_('No account tied to this seedphrase'), exit=True)
return
_dlg.close()
self.change_password_dialog(wallet=wallet, mode='restore')
return
from pudb import set_trace; set_trace()
wallet = self.wallet
#is_restore = bool(_dlg.__class__ == RestoreSeedDialog)
# Restore
if len(seed) == 128:
wallet.seed = ''
wallet.init_sequence(str(seed))
else:
wallet.seed = ''
wallet.init_seed(str(seed))
wallet.save_seed()
return self.change_network_dialog()
def init_seed_dialog(self, wallet=None, instance=None, password=None, def init_seed_dialog(self, wallet=None, instance=None, password=None,
wallet_name=None): wallet_name=None):
# renamed from show_seed() # renamed from show_seed()
@ -125,15 +173,16 @@ class InstallWizard(Widget):
Clock.schedule_once(lambda dt: Clock.schedule_once(lambda dt:
app.show_error(err)) app.show_error(err))
wallet.synchronize() # generate first addresses offline wallet.synchronize() # generate first addresses offline
self.waiting_dialog(partial(create, password)) self.waiting_dialog(partial(create, password),
on_complete=self.load_network)
from electrum_gui.kivy.dialog import InitSeedDialog
InitSeedDialog(message=msg2, InitSeedDialog(message=msg2,
seed_msg=brainwallet, seed_msg=brainwallet,
seed=seed, seed=seed,
on_release=on_ok_press).open() on_release=on_ok_press).open()
def change_password_dialog(self, wallet=None, instance=None): def change_password_dialog(self, wallet=None, instance=None, mode='create'):
"""Can be called directly (instance is None) """Can be called directly (instance is None)
or from a callback (instance is not None)""" or from a callback (instance is not None)"""
@ -154,13 +203,14 @@ class InstallWizard(Widget):
msg = _("Please choose a password to encrypt your wallet keys.") +\ msg = _("Please choose a password to encrypt your wallet keys.") +\
'\n' + _("Leave these fields empty if you want to disable" + \ '\n' + _("Leave these fields empty if you want to disable" + \
" encryption.") " encryption.")
mode = 'create'
def on_release(_dlg, _btn): def on_release(_dlg, _btn):
ti_password = _dlg.ids.ti_password ti_password = _dlg.ids.ti_password
ti_new_password = _dlg.ids.ti_new_password ti_new_password = _dlg.ids.ti_new_password
ti_confirm_password = _dlg.ids.ti_confirm_password ti_confirm_password = _dlg.ids.ti_confirm_password
if _btn != _dlg.ids.next: if _btn != _dlg.ids.next:
if mode == 'restore':
return
_dlg.close() _dlg.close()
if not instance: if not instance:
CreateRestoreDialog( CreateRestoreDialog(
@ -185,25 +235,29 @@ class InstallWizard(Widget):
ti_password.focus = True ti_password.focus = True
return app.show_error(_('Passwords do not match')) return app.show_error(_('Passwords do not match'))
if not instance: if mode == 'restore':
_dlg.close() _dlg.close()
self.init_seed_dialog(password=new_password, wallet.save_seed(new_password)
self.load_network(wallet, mode='restore')
return
if not instance:
# create
_dlg.close()
self.load_network(wallet, mode='create')
return self.init_seed_dialog(password=new_password,
wallet=wallet, wallet=wallet,
wallet_name=wallet_name) wallet_name=wallet_name)
return
try: try:
seed = wallet.decode_seed(password) seed = wallet.decode_seed(password)
except BaseException: except BaseException:
return MessageBoxError( return app.show_error(_('Incorrect Password'))
message=_('Incorrect Password')).open()
# test carefully # test carefully
try: try:
wallet.update_password(seed, password, new_password) wallet.update_password(seed, password, new_password)
except BaseException: except BaseException:
return MessageBoxExit( return app.show_error(_('Failed to update password'), exit=True)
message=_('Failed to update password')).open()
else: else:
app.show_info_bubble( app.show_info_bubble(
text=_('Password successfully updated'), duration=1, text=_('Password successfully updated'), duration=1,
@ -213,12 +267,56 @@ class InstallWizard(Widget):
if instance is None: # in initial phase if instance is None: # in initial phase
self.load_wallet() self.load_wallet()
self.app.gui.main_gui.update_wallet() self.app.update_wallet()
from electrum_gui.kivy.dialog import ChangePasswordDialog
cpd = ChangePasswordDialog( cpd = ChangePasswordDialog(
message=msg, message=msg,
mode=mode, mode=mode,
on_release=on_release).open() on_release=on_release).open()
def load_network(self, wallet, mode=None):
#if not self.config.get('server'):
if not self.network:
return wallet.start_threads(self.network)
if not self.network.interfaces:
app.show_error(_('You are offline'))
self.network.stop()
self.network = None
return wallet.start_threads(self.network)
if mode not in ('restore', 'create'):
self.network_dialog()
return wallet.start_threads(self.network)
self.config.set_key('auto_cycle', True, True)
wallet.start_threads(self.network)
def get_text(text):
def set_text(*l): app.info_bubble.ids.lbl.text=text
Clock.schedule_once(set_text)
def on_complete(*l):
if not self.network:
app.show_info_bubble(
text=_("This wallet was restored offline. It may contain"
" more addresses than displayed."),
width='200dp',
pos=Window.center)
return
if wallet.is_found():
app.show_info_bubble(_("Recovery successful"),
width='200dp',
pos=Window.center)
else:
app.show_info_bubble(_("No transactions found for this seed"),
width='200dp',
pos=Window.center)
self.waiting_dialog(lambda: wallet.restore(get_text),
on_complete=on_complete)
def on_wizard_complete(self, instance, wallet): def on_wizard_complete(self, instance, wallet):
pass pass

View File

@ -92,9 +92,9 @@
size_hint: None, None size_hint: None, None
width: '270dp' if root.fs else min(self.width, dp(270)) width: '270dp' if root.fs else min(self.width, dp(270))
height: self.width if self.fs else (lbl.texture_size[1] + dp(27)) height: self.width if self.fs else (lbl.texture_size[1] + dp(27))
on_touch_down: self.hide()
BoxLayout: BoxLayout:
padding: '5dp' padding: '5dp'
spacing: '5dp'
Widget: Widget:
size_hint: None, 1 size_hint: None, 1
width: '4dp' if root.fs else '2dp' width: '4dp' if root.fs else '2dp'
@ -179,8 +179,8 @@
size_hint: 1, None size_hint: 1, None
height: grid_logo.height/2.5 if self.opacity else 0 height: grid_logo.height/2.5 if self.opacity else 0
Widget: Widget:
size_hint: 1, None size_hint: None, None
height: '5dp' size: '5dp', '5dp'
GridLayout: GridLayout:
cols: 1 cols: 1
id: crcontent id: crcontent
@ -219,6 +219,53 @@
# text: _('Create a Watching only wallet') # text: _('Create a Watching only wallet')
# root: root # root: root
<RestoreSeedDialog>
GridLayout
# leave room for future selection of gap through a widget
# removed for mobile
id: text_input_gap
text: '5'
cols: 1
padding: 0, '12dp'
orientation: 'vertical'
spacing: '12dp'
size_hint: 1, None
height: self.minimum_height
CreateAccountTextInput:
id: text_input_seed
size_hint: 1, None
height: '110dp'
hint_text:
_('Enter your seedphrase')
Label:
font_size: '12sp'
text_size: self.width, None
size_hint: 1, None
height: self.texture_size[1]
halign: 'justify'
valign: 'middle'
text:
_('If you need additional information, please check '
'[color=#0000ff][ref=1]'
'https://electrum.org/faq.html#seed[/ref][/color]')
on_ref_press:
import webbrowser
webbrowser.open('https://electrum.org/faq.html#seed')
GridLayout:
rows: 1
spacing: '12dp'
size_hint: 1, None
height: self.minimum_height
CreateAccountButtonBlue:
id: back
text: _('Back')
root: root
CreateAccountButtonGreen:
id: next
text: _('Next')
root: root
<InitSeedDialog> <InitSeedDialog>
spacing: '12dp' spacing: '12dp'
GridLayout: GridLayout:
@ -281,37 +328,50 @@
<ChangePasswordDialog> <ChangePasswordDialog>
padding: '7dp' padding: '7dp'
CreateAccountTextInput: GridLayout:
id: ti_wallet_name
hint_text: 'Your Wallet Name'
multiline: False
on_text_validate:
next = ti_new_password if ti_password.disabled else ti_password
next.focus = True
CreateAccountTextInput:
id: ti_password
hint_text: 'Enter old pincode'
size_hint_y: None size_hint_y: None
height: 0 if self.disabled else '38sp' height: self.minimum_height
password: True cols: 1
disabled: True if root.mode in ('new', 'create') else False CreateAccountTextInput:
opacity: 0 if self.disabled else 1 id: ti_wallet_name
multiline: False hint_text: 'Your Wallet Name'
on_text_validate: multiline: False
#root.validate_old_password() on_text_validate:
ti_new_password.focus = True next = ti_new_password if ti_password.disabled else ti_password
CreateAccountTextInput: next.focus = True
id: ti_new_password Widget:
hint_text: 'Enter new pincode' size_hint_y: None
multiline: False height: '13dp'
password: True CreateAccountTextInput:
on_text_validate: ti_confirm_password.focus = True id: ti_password
CreateAccountTextInput: hint_text: 'Enter old pincode'
id: ti_confirm_password size_hint_y: None
hint_text: 'Confirm pincode' height: 0 if self.disabled else '38sp'
password: True password: True
multiline: False disabled: True if root.mode in ('new', 'create', 'restore') else False
on_text_validate: root.validate_new_passowrd() opacity: 0 if self.disabled else 1
multiline: False
on_text_validate:
#root.validate_old_password()
ti_new_password.focus = True
Widget:
size_hint_y: None
height: 0 if ti_password.disabled else '13dp'
CreateAccountTextInput:
id: ti_new_password
hint_text: 'Enter new pincode'
multiline: False
password: True
on_text_validate: ti_confirm_password.focus = True
Widget:
size_hint_y: None
height: '13dp'
CreateAccountTextInput:
id: ti_confirm_password
hint_text: 'Confirm pincode'
password: True
multiline: False
on_text_validate: root.validate_new_password()
Widget Widget
GridLayout: GridLayout:
rows: 1 rows: 1
@ -322,9 +382,10 @@
id: back id: back
text: _('Back') text: _('Back')
root: root root: root
disabled: True if root.mode[0] == 'r' else self.disabled
CreateAccountButtonGreen: CreateAccountButtonGreen:
id: next id: next
text: _('Next') text: _('Confirm') if root.mode[0] == 'r' else _('Next')
root: root root: root
############################################### ###############################################

View File

@ -106,7 +106,7 @@ class ElectrumWindow(App):
def on_start(self): def on_start(self):
Window.bind(size=self.on_size, Window.bind(size=self.on_size,
on_keyboard=self.on_keyboard) on_keyboard=self.on_keyboard)
Window.bind(keyboard_height=self.on_keyboard_height) #Window.bind(keyboard_height=self.on_keyboard_height)
self.on_size(Window, Window.size) self.on_size(Window, Window.size)
config = self.electrum_config config = self.electrum_config
storage = WalletStorage(config) storage = WalletStorage(config)
@ -229,7 +229,8 @@ class ElectrumWindow(App):
def show_error(self, error, def show_error(self, error,
width='200dp', width='200dp',
pos=None, pos=None,
arrow_pos=None): arrow_pos=None,
exit=False):
''' Show a error Message Bubble. ''' Show a error Message Bubble.
''' '''
self.show_info_bubble( self.show_info_bubble(
@ -237,7 +238,8 @@ class ElectrumWindow(App):
icon='atlas://gui/kivy/theming/light/error', icon='atlas://gui/kivy/theming/light/error',
width=width, width=width,
pos=pos or Window.center, pos=pos or Window.center,
arrow_pos=arrow_pos) arrow_pos=arrow_pos,
exit=exit)
def show_info_bubble(self, def show_info_bubble(self,
text=_('Hello World'), text=_('Hello World'),
@ -246,7 +248,8 @@ class ElectrumWindow(App):
arrow_pos='bottom_mid', arrow_pos='bottom_mid',
width=None, width=None,
icon='', icon='',
modal=False): modal=False,
exit=False):
'''Method to show a Information Bubble '''Method to show a Information Bubble
.. parameters:: .. parameters::
@ -291,4 +294,4 @@ class ElectrumWindow(App):
info_bubble.dim_background = False info_bubble.dim_background = False
info_bubble.background_image = 'atlas://data/images/defaulttheme/bubble' info_bubble.background_image = 'atlas://data/images/defaulttheme/bubble'
info_bubble.message = text info_bubble.message = text
info_bubble.show(pos, duration, width, modal=modal) info_bubble.show(pos, duration, width, modal=modal, exit=exit)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 716 KiB

After

Width:  |  Height:  |  Size: 475 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

View File

@ -1 +1 @@
{"light-1.png": {"icon_border": [475, 958, 64, 64], "tab_btn_disabled": [625, 924, 32, 32], "tab_btn_pressed": [693, 924, 32, 32], "btn_send_nfc": [1003, 968, 18, 15], "logo_atom_dull": [607, 958, 64, 64], "tab": [871, 958, 64, 64], "logo": [149, 894, 128, 128], "confirmed": [409, 958, 64, 64], "pen": [739, 958, 64, 64], "star_big_inactive": [279, 894, 128, 128], "action_group_dark": [2, 787, 33, 48], "mail_icon": [409, 902, 65, 54], "tab_btn": [659, 924, 32, 32], "btn_send_address": [1003, 985, 18, 15], "add_contact": [538, 913, 51, 43], "manualentry": [2, 888, 145, 134], "wallets": [727, 924, 32, 32], "shadow": [805, 958, 64, 64], "unconfirmed": [937, 958, 64, 64], "info": [541, 958, 64, 64], "nfc": [673, 958, 64, 64], "settings": [591, 924, 32, 32], "closebutton": [476, 913, 60, 43], "wallet": [53, 842, 49, 44], "contact": [2, 837, 49, 49], "dialog": [1003, 1002, 18, 20]}, "light-0.png": {"globe": [937, 65, 72, 72], "btn_create_account": [840, 394, 64, 32], "card_top": [770, 31, 32, 16], "qrcode": [805, 508, 145, 145], "close": [886, 168, 88, 88], "btn_create_act_disabled": [946, 394, 32, 32], "create_act_text": [998, 430, 22, 10], "card_bottom": [985, 150, 32, 16], "carousel_deselected": [952, 589, 64, 64], "network": [976, 208, 48, 48], "blue_bg_round_rb": [886, 146, 31, 20], "action_bar": [976, 170, 36, 36], "arrow_back": [974, 442, 50, 50], "card_btn": [906, 394, 38, 32], "tab_disabled": [644, 394, 96, 32], "lightblue_bg_round_lb": [919, 146, 31, 20], "white_bg_round_top": [952, 146, 31, 20], "tab_strip": [742, 394, 96, 32], "important": [770, 49, 88, 88], "gear": [644, 494, 159, 159], "stepper_left": [376, 20, 392, 117], "nfc_stage_one": [376, 258, 489, 122], "nfc_clock": [644, 655, 372, 367], "clock1": [644, 428, 64, 64], "clock2": [710, 428, 64, 64], "clock3": [776, 428, 64, 64], "clock4": [842, 428, 64, 64], "paste_icon": [860, 60, 75, 77], "carousel_selected": [952, 523, 64, 64], "card": [980, 394, 32, 32], "electrum_icon640": [2, 382, 640, 640], "btn_nfc": [1011, 125, 13, 12], "create_act_text_active": [974, 430, 22, 10], "stepper_full": [376, 139, 392, 117], "nfc_phone": [2, 13, 372, 367], "error": [867, 266, 128, 114], "textinput_active": [770, 142, 114, 114], "shadow_right": [952, 516, 32, 5], "clock5": [908, 428, 64, 64]}} {"light-0.png": {"closebutton": [962, 737, 60, 43], "card_top": [810, 328, 32, 16], "tab_btn_disabled": [674, 312, 32, 32], "tab_btn_pressed": [742, 312, 32, 32], "globe": [884, 219, 72, 72], "btn_send_nfc": [996, 514, 18, 15], "shadow_right": [958, 220, 32, 5], "logo_atom_dull": [528, 346, 64, 64], "tab": [792, 346, 64, 64], "logo": [457, 163, 128, 128], "qrcode": [163, 146, 145, 145], "close": [906, 441, 88, 88], "btn_create_act_disabled": [953, 169, 32, 32], "create_act_text": [996, 490, 22, 10], "card_bottom": [962, 719, 32, 16], "confirmed": [896, 716, 64, 64], "carousel_deselected": [958, 227, 64, 64], "network": [499, 296, 48, 48], "blue_bg_round_rb": [906, 419, 31, 20], "action_bar": [602, 308, 36, 36], "pen": [660, 346, 64, 64], "arrow_back": [396, 294, 50, 50], "clock3": [698, 716, 64, 64], "contact": [448, 295, 49, 49], "star_big_inactive": [587, 163, 128, 128], "lightblue_bg_round_lb": [939, 419, 31, 20], "manualentry": [310, 157, 145, 134], "stepper_restore_password": [396, 412, 392, 117], "tab_disabled": [717, 169, 96, 32], "mail_icon": [924, 356, 65, 54], "tab_strip": [815, 169, 96, 32], "tab_btn": [708, 312, 32, 32], "btn_create_account": [943, 792, 64, 32], "btn_send_address": [996, 720, 18, 15], "add_contact": [549, 301, 51, 43], "gear": [2, 132, 159, 159], "wallets": [776, 312, 32, 32], "stepper_left": [2, 412, 392, 117], "nfc_stage_one": [2, 531, 489, 122], "nfc_clock": [698, 782, 243, 240], "btn_nfc": [1009, 812, 13, 12], "textinput_active": [790, 415, 114, 114], "clock2": [943, 826, 64, 64], "nfc_phone": [2, 655, 372, 367], "clock4": [764, 716, 64, 64], "paste_icon": [807, 214, 75, 77], "shadow": [726, 346, 64, 64], "carousel_selected": [943, 958, 64, 64], "card": [987, 169, 32, 32], "unconfirmed": [858, 346, 64, 64], "info": [462, 346, 64, 64], "electrum_icon640": [376, 702, 320, 320], "action_group_dark": [991, 362, 33, 48], "nfc": [594, 346, 64, 64], "clock1": [943, 892, 64, 64], "create_act_text_active": [996, 502, 22, 10], "icon_border": [396, 346, 64, 64], "stepper_full": [493, 536, 392, 117], "card_btn": [913, 169, 38, 32], "wallet": [376, 656, 49, 44], "important": [717, 203, 88, 88], "dialog": [1005, 419, 18, 20], "error": [887, 539, 128, 114], "stepper_restore_seed": [2, 293, 392, 117], "white_bg_round_top": [972, 419, 31, 20], "settings": [640, 312, 32, 32], "clock5": [830, 716, 64, 64]}}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 526 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 33 KiB