Add Kivy myaddress screen
This commit is contained in:
parent
09cc100424
commit
4f48bfb3fb
232
src/bitmessagekivy/baseclass/myaddress.py
Normal file
232
src/bitmessagekivy/baseclass/myaddress.py
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
# pylint: disable=unused-argument, import-error, no-member, attribute-defined-outside-init
|
||||||
|
# pylint: disable=no-name-in-module, too-few-public-methods, too-many-instance-attributes
|
||||||
|
|
||||||
|
"""
|
||||||
|
myaddress.py
|
||||||
|
==============
|
||||||
|
All generated addresses are managed in MyAddress
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
from kivy.clock import Clock
|
||||||
|
from kivy.properties import (
|
||||||
|
ListProperty,
|
||||||
|
StringProperty
|
||||||
|
)
|
||||||
|
from kivy.uix.screenmanager import Screen, ScreenManagerException
|
||||||
|
from kivy.app import App
|
||||||
|
|
||||||
|
from kivymd.uix.list import (
|
||||||
|
IRightBodyTouch,
|
||||||
|
TwoLineAvatarIconListItem,
|
||||||
|
)
|
||||||
|
from kivymd.uix.selectioncontrol import MDSwitch
|
||||||
|
|
||||||
|
from pybitmessage.bmconfigparser import config
|
||||||
|
|
||||||
|
from pybitmessage.bitmessagekivy.get_platform import platform
|
||||||
|
from pybitmessage.bitmessagekivy.baseclass.common import (
|
||||||
|
avatar_image_first_letter, AvatarSampleWidget, ThemeClsColor,
|
||||||
|
toast, empty_screen_label, load_image_path
|
||||||
|
)
|
||||||
|
|
||||||
|
from pybitmessage.bitmessagekivy.baseclass.popup import MyaddDetailPopup
|
||||||
|
from pybitmessage.bitmessagekivy.baseclass.myaddress_widgets import HelperMyAddress
|
||||||
|
|
||||||
|
|
||||||
|
class ToggleBtn(IRightBodyTouch, MDSwitch):
|
||||||
|
"""ToggleBtn class for kivy UI"""
|
||||||
|
|
||||||
|
|
||||||
|
class CustomTwoLineAvatarIconListItem(TwoLineAvatarIconListItem):
|
||||||
|
"""CustomTwoLineAvatarIconListItem class for kivy Ui"""
|
||||||
|
|
||||||
|
|
||||||
|
class MyAddress(Screen, HelperMyAddress):
|
||||||
|
"""MyAddress screen class for kivy Ui"""
|
||||||
|
|
||||||
|
address_label = StringProperty()
|
||||||
|
text_address = StringProperty()
|
||||||
|
addresses_list = ListProperty()
|
||||||
|
has_refreshed = True
|
||||||
|
is_add_created = False
|
||||||
|
label_str = "Yet no address is created by user!!!!!!!!!!!!!"
|
||||||
|
no_search_res_found = "No search result found"
|
||||||
|
min_scroll_y_limit = -0.0
|
||||||
|
scroll_y_step = 0.06
|
||||||
|
number_of_addresses = 20
|
||||||
|
addresses_at_a_time = 15
|
||||||
|
canvas_color_black = [0, 0, 0, 0]
|
||||||
|
canvas_color_gray = [0.5, 0.5, 0.5, 0.5]
|
||||||
|
is_android_width = .9
|
||||||
|
other_platform_width = .6
|
||||||
|
disabled_addr_width = .8
|
||||||
|
other_platform_disabled_addr_width = .55
|
||||||
|
max_scroll_limit = 1.0
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
"""Clock schdule for method Myaddress accounts"""
|
||||||
|
super(MyAddress, self).__init__(*args, **kwargs)
|
||||||
|
self.image_dir = load_image_path()
|
||||||
|
self.kivy_running_app = App.get_running_app()
|
||||||
|
self.kivy_state = self.kivy_running_app.kivy_state_obj
|
||||||
|
|
||||||
|
Clock.schedule_once(self.init_ui, 0)
|
||||||
|
|
||||||
|
def init_ui(self, dt=0):
|
||||||
|
"""Clock schdule for method Myaddress accounts"""
|
||||||
|
self.addresses_list = config.addresses()
|
||||||
|
if self.kivy_state.searching_text:
|
||||||
|
self.ids.refresh_layout.scroll_y = self.max_scroll_limit
|
||||||
|
filtered_list = [
|
||||||
|
x for x in config.addresses()
|
||||||
|
if self.filter_address(x)
|
||||||
|
]
|
||||||
|
self.addresses_list = filtered_list
|
||||||
|
self.addresses_list = [obj for obj in reversed(self.addresses_list)]
|
||||||
|
self.ids.tag_label.text = ''
|
||||||
|
if self.addresses_list:
|
||||||
|
self.ids.tag_label.text = 'My Addresses'
|
||||||
|
self.has_refreshed = True
|
||||||
|
self.set_mdList(0, self.addresses_at_a_time)
|
||||||
|
self.ids.refresh_layout.bind(scroll_y=self.check_scroll_y)
|
||||||
|
else:
|
||||||
|
self.ids.ml.add_widget(empty_screen_label(self.label_str, self.no_search_res_found))
|
||||||
|
if not self.kivy_state.searching_text and not self.is_add_created:
|
||||||
|
try:
|
||||||
|
self.manager.current = 'login'
|
||||||
|
except ScreenManagerException:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_address_list(self, first_index, last_index, data):
|
||||||
|
"""Getting address and append to the list"""
|
||||||
|
for address in self.addresses_list[first_index:last_index]:
|
||||||
|
data.append({
|
||||||
|
'text': config.get(address, 'label'),
|
||||||
|
'secondary_text': address}
|
||||||
|
)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def set_address_to_widget(self, item):
|
||||||
|
"""Setting address to the widget"""
|
||||||
|
is_enable = config.getboolean(item['secondary_text'], 'enabled')
|
||||||
|
meny = CustomTwoLineAvatarIconListItem(
|
||||||
|
text=item['text'], secondary_text=item['secondary_text'],
|
||||||
|
theme_text_color='Custom' if is_enable else 'Primary',
|
||||||
|
text_color=ThemeClsColor,)
|
||||||
|
try:
|
||||||
|
meny.canvas.children[3].rgba = self.canvas_color_black if is_enable else self.canvas_color
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
meny.add_widget(AvatarSampleWidget(
|
||||||
|
source=os.path.join(
|
||||||
|
self.image_dir, "text_images", "{}.png".format(avatar_image_first_letter(
|
||||||
|
item["text"].strip())))
|
||||||
|
))
|
||||||
|
meny.bind(on_press=partial(
|
||||||
|
self.myadd_detail, item['secondary_text'], item['text']))
|
||||||
|
self.set_address_status(item, meny, is_enable)
|
||||||
|
|
||||||
|
def set_address_status(self, item, meny, is_enable):
|
||||||
|
"""Setting the identity status enable/disable on UI"""
|
||||||
|
if self.kivy_state.association == item['secondary_text'] and is_enable:
|
||||||
|
meny.add_widget(self.is_active_badge())
|
||||||
|
else:
|
||||||
|
meny.add_widget(ToggleBtn(active=True if is_enable else False))
|
||||||
|
self.ids.ml.add_widget(meny)
|
||||||
|
|
||||||
|
def set_mdList(self, first_index, last_index):
|
||||||
|
"""Creating the mdlist"""
|
||||||
|
data = []
|
||||||
|
self.get_address_list(first_index, last_index, data)
|
||||||
|
for item in data:
|
||||||
|
self.set_address_to_widget(item)
|
||||||
|
|
||||||
|
def check_scroll_y(self, instance, somethingelse):
|
||||||
|
"""Load data on Scroll down"""
|
||||||
|
if self.ids.refresh_layout.scroll_y <= self.min_scroll_y_limit and self.has_refreshed:
|
||||||
|
self.ids.refresh_layout.scroll_y = self.scroll_y_step
|
||||||
|
my_addresses = len(self.ids.ml.children)
|
||||||
|
if my_addresses != len(self.addresses_list):
|
||||||
|
self.update_addressBook_on_scroll(my_addresses)
|
||||||
|
self.has_refreshed = (
|
||||||
|
True if my_addresses != len(self.addresses_list) else False
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_addressBook_on_scroll(self, my_addresses):
|
||||||
|
"""Loads more data on scroll down"""
|
||||||
|
self.set_mdList(my_addresses, my_addresses + self.number_of_addresses)
|
||||||
|
|
||||||
|
def myadd_detail(self, fromaddress, label, *args):
|
||||||
|
"""Load myaddresses details"""
|
||||||
|
if config.get(fromaddress, 'enabled'):
|
||||||
|
obj = MyaddDetailPopup()
|
||||||
|
self.address_label = obj.address_label = label
|
||||||
|
self.text_address = obj.address = fromaddress
|
||||||
|
width = self.is_android_width if platform == 'android' else self.other_platform_width
|
||||||
|
self.myadddetail_popup = self.myaddress_detail_popup(obj, width)
|
||||||
|
self.myadddetail_popup.auto_dismiss = False
|
||||||
|
self.myadddetail_popup.open()
|
||||||
|
else:
|
||||||
|
width = self.disabled_addr_width if platform == 'android' else self.other_platform_disabled_addr_width
|
||||||
|
self.dialog_box = self.inactive_address_popup(width, self.callback_for_menu_items)
|
||||||
|
self.dialog_box.open()
|
||||||
|
|
||||||
|
def callback_for_menu_items(self, text_item, *arg):
|
||||||
|
"""Callback of inactive address alert box"""
|
||||||
|
self.dialog_box.dismiss()
|
||||||
|
toast(text_item)
|
||||||
|
|
||||||
|
def refresh_callback(self, *args):
|
||||||
|
"""Method updates the state of application,
|
||||||
|
While the spinner remains on the screen"""
|
||||||
|
def refresh_callback(interval):
|
||||||
|
"""Method used for loading the myaddress screen data"""
|
||||||
|
self.kivy_state.searching_text = ''
|
||||||
|
self.ids.search_bar.ids.search_field.text = ''
|
||||||
|
self.has_refreshed = True
|
||||||
|
self.ids.ml.clear_widgets()
|
||||||
|
self.init_ui()
|
||||||
|
self.ids.refresh_layout.refresh_done()
|
||||||
|
Clock.schedule_once(self.address_permision_callback, 0)
|
||||||
|
Clock.schedule_once(refresh_callback, 1)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def filter_address(address):
|
||||||
|
"""It will return True if search is matched"""
|
||||||
|
searched_text = App.get_running_app().kivy_state_obj.searching_text.lower()
|
||||||
|
return bool(config.search_addresses(address, searched_text))
|
||||||
|
|
||||||
|
def disable_address_ui(self, address, instance):
|
||||||
|
"""This method is used to disable addresses from UI"""
|
||||||
|
config.disable_address(address)
|
||||||
|
instance.parent.parent.theme_text_color = 'Primary'
|
||||||
|
instance.parent.parent.canvas.children[3].rgba = MyAddress.canvas_color_gray
|
||||||
|
toast('Address disabled')
|
||||||
|
Clock.schedule_once(self.address_permision_callback, 0)
|
||||||
|
|
||||||
|
def enable_address_ui(self, address, instance):
|
||||||
|
"""This method is used to enable addresses from UI"""
|
||||||
|
config.enable_address(address)
|
||||||
|
instance.parent.parent.theme_text_color = 'Custom'
|
||||||
|
instance.parent.parent.canvas.children[3].rgba = MyAddress.canvas_color_black
|
||||||
|
toast('Address Enabled')
|
||||||
|
Clock.schedule_once(self.address_permision_callback, 0)
|
||||||
|
|
||||||
|
def address_permision_callback(self, dt=0):
|
||||||
|
"""callback for enable or disable addresses"""
|
||||||
|
addresses = [addr for addr in config.addresses()
|
||||||
|
if config.getboolean(str(addr), 'enabled')]
|
||||||
|
self.parent.parent.ids.content_drawer.ids.identity_dropdown.values = addresses
|
||||||
|
# self.parent.parent.ids.sc3.children[1].ids.btn.values = addresses
|
||||||
|
self.kivy_running_app.identity_list = addresses
|
||||||
|
|
||||||
|
def toggleAction(self, instance):
|
||||||
|
"""This method is used for enable or disable address"""
|
||||||
|
addr = instance.parent.parent.secondary_text
|
||||||
|
if instance.active:
|
||||||
|
self.enable_address_ui(addr, instance)
|
||||||
|
else:
|
||||||
|
self.disable_address_ui(addr, instance)
|
64
src/bitmessagekivy/baseclass/myaddress_widgets.py
Normal file
64
src/bitmessagekivy/baseclass/myaddress_widgets.py
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
# pylint: disable=too-many-arguments, no-name-in-module, import-error
|
||||||
|
# pylint: disable=too-few-public-methods, no-member, too-many-ancestors
|
||||||
|
|
||||||
|
"""
|
||||||
|
MyAddress widgets are here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from kivymd.uix.button import MDFlatButton
|
||||||
|
from kivymd.uix.dialog import MDDialog
|
||||||
|
from kivymd.uix.label import MDLabel
|
||||||
|
from kivymd.uix.list import IRightBodyTouch
|
||||||
|
|
||||||
|
from pybitmessage.bitmessagekivy.get_platform import platform
|
||||||
|
from pybitmessage.bitmessagekivy.baseclass.common import ThemeClsColor
|
||||||
|
|
||||||
|
|
||||||
|
class BadgeText(IRightBodyTouch, MDLabel):
|
||||||
|
"""BadgeText class for kivy UI"""
|
||||||
|
|
||||||
|
|
||||||
|
class HelperMyAddress(object):
|
||||||
|
"""Widget used in MyAddress are here"""
|
||||||
|
dialog_height = .25
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_active_badge():
|
||||||
|
"""This function show the 'active' label of active Address."""
|
||||||
|
active_status = 'Active'
|
||||||
|
is_android_width = 90
|
||||||
|
width = 50
|
||||||
|
height = 60
|
||||||
|
badge_obj = BadgeText(
|
||||||
|
size_hint=(None, None),
|
||||||
|
size=[is_android_width if platform == 'android' else width, height],
|
||||||
|
text=active_status, halign='center',
|
||||||
|
font_style='Body1', theme_text_color='Custom',
|
||||||
|
text_color=ThemeClsColor, font_size='13sp'
|
||||||
|
)
|
||||||
|
return badge_obj
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def myaddress_detail_popup(obj, width):
|
||||||
|
"""This method show the details of address as popup opens."""
|
||||||
|
show_myaddress_dialogue = MDDialog(
|
||||||
|
type="custom",
|
||||||
|
size_hint=(width, HelperMyAddress.dialog_height),
|
||||||
|
content_cls=obj,
|
||||||
|
)
|
||||||
|
return show_myaddress_dialogue
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def inactive_address_popup(width, callback_for_menu_items):
|
||||||
|
"""This method shows the warning popup if the address is inactive"""
|
||||||
|
dialog_text = 'Address is not currently active. Please click on Toggle button to active it.'
|
||||||
|
dialog_box = MDDialog(
|
||||||
|
text=dialog_text,
|
||||||
|
size_hint=(width, HelperMyAddress.dialog_height),
|
||||||
|
buttons=[
|
||||||
|
MDFlatButton(
|
||||||
|
text="Ok", on_release=lambda x: callback_for_menu_items("Ok")
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
return dialog_box
|
|
@ -49,7 +49,7 @@
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
size: dp(36), dp(48)
|
size: dp(36), dp(48)
|
||||||
pos_hint: {'center_x': .95, 'center_y': .4}
|
pos_hint: {'center_x': .95, 'center_y': .4}
|
||||||
on_active: app.root.ids.sc10.toggleAction(self)
|
on_active: app.root.ids.id_myaddress.toggleAction(self)
|
||||||
|
|
||||||
<CustomTwoLineAvatarIconListItem>:
|
<CustomTwoLineAvatarIconListItem>:
|
||||||
canvas:
|
canvas:
|
||||||
|
|
|
@ -30,4 +30,4 @@
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
size: dp(36), dp(48)
|
size: dp(36), dp(48)
|
||||||
pos_hint: {'center_x': .95, 'center_y': .4}
|
pos_hint: {'center_x': .95, 'center_y': .4}
|
||||||
on_active: app.root.ids.sc10.toggleAction(self)
|
on_active: app.root.ids.id_myaddress.toggleAction(self)
|
||||||
|
|
|
@ -212,6 +212,8 @@ MDNavigationLayout:
|
||||||
id:sc6
|
id:sc6
|
||||||
Random:
|
Random:
|
||||||
id:id_newidentity
|
id:id_newidentity
|
||||||
|
MyAddress:
|
||||||
|
id:id_myaddress
|
||||||
|
|
||||||
MDNavigationDrawer:
|
MDNavigationDrawer:
|
||||||
id: nav_drawer
|
id: nav_drawer
|
||||||
|
|
|
@ -2,5 +2,10 @@
|
||||||
"Login": {
|
"Login": {
|
||||||
"kv_string": "login",
|
"kv_string": "login",
|
||||||
"Import": "from pybitmessage.bitmessagekivy.baseclass.login import *"
|
"Import": "from pybitmessage.bitmessagekivy.baseclass.login import *"
|
||||||
|
},
|
||||||
|
"My addresses": {
|
||||||
|
"kv_string": "myaddress",
|
||||||
|
"name_screen": "myaddress",
|
||||||
|
"Import": "from pybitmessage.bitmessagekivy.baseclass.myaddress import MyAddress"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue
Block a user