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: dp(36), dp(48)
|
||||
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>:
|
||||
canvas:
|
||||
|
|
|
@ -30,4 +30,4 @@
|
|||
size_hint: None, None
|
||||
size: dp(36), dp(48)
|
||||
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
|
||||
Random:
|
||||
id:id_newidentity
|
||||
MyAddress:
|
||||
id:id_myaddress
|
||||
|
||||
MDNavigationDrawer:
|
||||
id: nav_drawer
|
||||
|
|
|
@ -2,5 +2,10 @@
|
|||
"Login": {
|
||||
"kv_string": "login",
|
||||
"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