diff --git a/src/bitmessagekivy/baseclass/myaddress.py b/src/bitmessagekivy/baseclass/myaddress.py index 0a46bae98..6534c1a05 100644 --- a/src/bitmessagekivy/baseclass/myaddress.py +++ b/src/bitmessagekivy/baseclass/myaddress.py @@ -4,93 +4,81 @@ """ myaddress.py ============== -All generated addresses are managed in MyAddress +This module manages all generated addresses in MyAddress. """ import os from functools import partial from kivy.clock import Clock -from kivy.properties import ( - ListProperty, - StringProperty -) +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.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""" + """UI Toggle button""" class CustomTwoLineAvatarIconListItem(TwoLineAvatarIconListItem): - """CustomTwoLineAvatarIconListItem class for kivy Ui""" + """Customized list item with Avatar and Icon.""" class MyAddress(Screen, HelperMyAddress): - """MyAddress screen class for kivy Ui""" + """Screen class to manage user addresses in the Kivy app.""" 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 + label_str = "No addresses have been created by the user." + no_search_res_found = "No search results 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 + is_android_width = 0.9 + other_platform_width = 0.6 + disabled_addr_width = 0.8 + other_platform_disabled_addr_width = 0.55 max_scroll_limit = 1.0 def __init__(self, *args, **kwargs): - """Clock schdule for method Myaddress accounts""" - super(MyAddress, self).__init__(*args, **kwargs) + """Initialize MyAddress screen and schedule UI setup.""" + super().__init__(*args, **kwargs) # pylint: disable=missing-super-argument 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""" + def init_ui(self, _dt=0): + """Initialize the address UI and load the list of addresses.""" 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 = [ + address for address in config.addresses() if self.filter_address(address) ] - self.addresses_list = filtered_list - self.addresses_list = [obj for obj in reversed(self.addresses_list)] + self.addresses_list.reverse() 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.populate_address_list(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)) @@ -100,131 +88,125 @@ def init_ui(self, dt=0): 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( + def populate_address_list(self, first_index, last_index): + """Populate the address list within the specified range.""" + data = self.get_address_list(first_index, last_index) + for item in data: + self.create_address_widget(item) + + def get_address_list(self, first_index, last_index): + """Fetch address details and return them as a list of dictionaries.""" + return [ + {'text': config.get(address, 'label'), 'secondary_text': address} + for address in self.addresses_list[first_index:last_index] + ] + + def create_address_widget(self, item): + """Create and configure a UI widget for each address.""" + is_enabled = config.getboolean(item['secondary_text'], 'enabled') + address_widget = CustomTwoLineAvatarIconListItem( text=item['text'], secondary_text=item['secondary_text'], - theme_text_color='Custom' if is_enable else 'Primary', - text_color=ThemeClsColor,) - meny.canvas.children[3].rgba = \ - self.canvas_color_black if is_enable else self.canvas_color - 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.selected_address == item['secondary_text'] and is_enable: - meny.add_widget(self.is_active_badge()) + theme_text_color='Custom' if is_enabled else 'Primary', + text_color=ThemeClsColor + ) + address_widget.canvas.children[3].rgba = self.canvas_color_black if is_enabled else self.canvas_color_gray + avatar_image_path = os.path.join( + self.image_dir, "text_images", f"{avatar_image_first_letter(item['text'].strip())}.png" # noqa: E999 + ) + address_widget.add_widget(AvatarSampleWidget(source=avatar_image_path)) + address_widget.bind(on_press=partial(self.show_address_details, item['secondary_text'], item['text'])) + self.configure_address_status(item, address_widget, is_enabled) + + def configure_address_status(self, item, widget, is_enabled): + """Configure the address status and add appropriate toggle or badge.""" + if self.kivy_state.selected_address == item['secondary_text'] and is_enabled: + widget.add_widget(self.is_active_badge()) else: - meny.add_widget(ToggleBtn(active=True if is_enable else False)) - self.ids.ml.add_widget(meny) + widget.add_widget(ToggleBtn(active=is_enabled)) + self.ids.ml.add_widget(widget) - 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""" + def check_scroll_y(self, _instance, _scroll_value): + """Load more addresses when the user scrolls 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.getboolean(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) + current_address_count = len(self.ids.ml.children) + if current_address_count != len(self.addresses_list): + self.load_more_addresses(current_address_count) + self.has_refreshed = (current_address_count != len(self.addresses_list)) + + def load_more_addresses(self, current_address_count): + """Load additional addresses when scrolling.""" + self.populate_address_list(current_address_count, current_address_count + self.number_of_addresses) + + def show_address_details(self, address, label, *args): + """Display address details in a popup.""" + if config.getboolean(address, 'enabled'): + detail_popup = MyaddDetailPopup() + self.address_label = detail_popup.address_label = label + self.text_address = detail_popup.address = address + popup_width = self.is_android_width if platform == 'android' else self.other_platform_width + self.myadddetail_popup = self.create_address_detail_popup(detail_popup, popup_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) + popup_width = ( + self.disabled_addr_width if platform == 'android' else self.other_platform_disabled_addr_width) + self.dialog_box = self.create_inactive_address_popup(popup_width, self.inactive_address_callback) self.dialog_box.open() - def callback_for_menu_items(self, text_item, *arg): - """Callback of inactive address alert box""" + def inactive_address_callback(self, selected_item, *args): + """Handle user action from the inactive address alert.""" self.dialog_box.dismiss() - toast(text_item) + toast(selected_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""" + """Refresh the screen by resetting the UI.""" + def update_ui(_interval): + """Clear search input and refresh the address list.""" 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) + Clock.schedule_once(self.update_enabled_addresses, 0) + + Clock.schedule_once(update_ui, 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)) + """Check if the current address matches the search term.""" + search_text = App.get_running_app().kivy_state_obj.searching_text.lower() + return config.search_addresses(address, search_text) def disable_address_ui(self, address, instance): - """This method is used to disable addresses from UI""" + """Disable the selected address in the 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) + Clock.schedule_once(self.update_enabled_addresses, 0) def enable_address_ui(self, address, instance): - """This method is used to enable addresses from UI""" + """Enable the selected address in the 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) + toast('Address enabled') + Clock.schedule_once(self.update_enabled_addresses, 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.id_create.children[1].ids.composer_dropdown.values = addresses - self.kivy_running_app.identity_list = addresses + def update_enabled_addresses(self, _dt=0): + """Update the list of enabled addresses after a change.""" + enabled_addresses = [addr for addr in config.addresses() if config.getboolean(addr, 'enabled')] + parent_ui = self.parent.parent.ids + parent_ui.content_drawer.ids.identity_dropdown.values = enabled_addresses + parent_ui.id_create.children[1].ids.composer_dropdown.values = enabled_addresses + self.kivy_running_app.identity_list = enabled_addresses def toggleAction(self, instance): - """This method is used for enable or disable address""" - addr = instance.parent.parent.secondary_text + """Toggle the enable/disable state of an address.""" + address = instance.parent.parent.secondary_text if instance.active: - self.enable_address_ui(addr, instance) + self.enable_address_ui(address, instance) else: - self.disable_address_ui(addr, instance) + self.disable_address_ui(address, instance)