/ src / bitmessagekivy / baseclass / myaddress.py
myaddress.py
  1  # pylint: disable=unused-argument, import-error, no-member, attribute-defined-outside-init
  2  # pylint: disable=no-name-in-module, too-few-public-methods, too-many-instance-attributes
  3  
  4  """
  5  myaddress.py
  6  ==============
  7  All generated addresses are managed in MyAddress
  8  """
  9  
 10  import os
 11  from functools import partial
 12  
 13  from kivy.clock import Clock
 14  from kivy.properties import (
 15      ListProperty,
 16      StringProperty
 17  )
 18  from kivy.uix.screenmanager import Screen, ScreenManagerException
 19  from kivy.app import App
 20  
 21  from kivymd.uix.list import (
 22      IRightBodyTouch,
 23      TwoLineAvatarIconListItem,
 24  )
 25  from kivymd.uix.selectioncontrol import MDSwitch
 26  
 27  from pybitmessage.bmconfigparser import config
 28  
 29  from pybitmessage.bitmessagekivy.get_platform import platform
 30  from pybitmessage.bitmessagekivy.baseclass.common import (
 31      avatar_image_first_letter, AvatarSampleWidget, ThemeClsColor,
 32      toast, empty_screen_label, load_image_path
 33  )
 34  
 35  from pybitmessage.bitmessagekivy.baseclass.popup import MyaddDetailPopup
 36  from pybitmessage.bitmessagekivy.baseclass.myaddress_widgets import HelperMyAddress
 37  
 38  
 39  class ToggleBtn(IRightBodyTouch, MDSwitch):
 40      """ToggleBtn class for kivy UI"""
 41  
 42  
 43  class CustomTwoLineAvatarIconListItem(TwoLineAvatarIconListItem):
 44      """CustomTwoLineAvatarIconListItem class for kivy Ui"""
 45  
 46  
 47  class MyAddress(Screen, HelperMyAddress):
 48      """MyAddress screen class for kivy Ui"""
 49  
 50      address_label = StringProperty()
 51      text_address = StringProperty()
 52      addresses_list = ListProperty()
 53      has_refreshed = True
 54      is_add_created = False
 55      label_str = "Yet no address is created by user!!!!!!!!!!!!!"
 56      no_search_res_found = "No search result found"
 57      min_scroll_y_limit = -0.0
 58      scroll_y_step = 0.06
 59      number_of_addresses = 20
 60      addresses_at_a_time = 15
 61      canvas_color_black = [0, 0, 0, 0]
 62      canvas_color_gray = [0.5, 0.5, 0.5, 0.5]
 63      is_android_width = .9
 64      other_platform_width = .6
 65      disabled_addr_width = .8
 66      other_platform_disabled_addr_width = .55
 67      max_scroll_limit = 1.0
 68  
 69      def __init__(self, *args, **kwargs):
 70          """Clock schdule for method Myaddress accounts"""
 71          super(MyAddress, self).__init__(*args, **kwargs)
 72          self.image_dir = load_image_path()
 73          self.kivy_running_app = App.get_running_app()
 74          self.kivy_state = self.kivy_running_app.kivy_state_obj
 75  
 76          Clock.schedule_once(self.init_ui, 0)
 77  
 78      def init_ui(self, dt=0):
 79          """Clock schdule for method Myaddress accounts"""
 80          self.addresses_list = config.addresses()
 81          if self.kivy_state.searching_text:
 82              self.ids.refresh_layout.scroll_y = self.max_scroll_limit
 83              filtered_list = [
 84                  x for x in config.addresses()
 85                  if self.filter_address(x)
 86              ]
 87              self.addresses_list = filtered_list
 88          self.addresses_list = [obj for obj in reversed(self.addresses_list)]
 89          self.ids.tag_label.text = ''
 90          if self.addresses_list:
 91              self.ids.tag_label.text = 'My Addresses'
 92              self.has_refreshed = True
 93              self.set_mdList(0, self.addresses_at_a_time)
 94              self.ids.refresh_layout.bind(scroll_y=self.check_scroll_y)
 95          else:
 96              self.ids.ml.add_widget(empty_screen_label(self.label_str, self.no_search_res_found))
 97              if not self.kivy_state.searching_text and not self.is_add_created:
 98                  try:
 99                      self.manager.current = 'login'
100                  except ScreenManagerException:
101                      pass
102  
103      def get_address_list(self, first_index, last_index, data):
104          """Getting address and append to the list"""
105          for address in self.addresses_list[first_index:last_index]:
106              data.append({
107                  'text': config.get(address, 'label'),
108                  'secondary_text': address}
109              )
110          return data
111  
112      def set_address_to_widget(self, item):
113          """Setting address to the widget"""
114          is_enable = config.getboolean(item['secondary_text'], 'enabled')
115          meny = CustomTwoLineAvatarIconListItem(
116              text=item['text'], secondary_text=item['secondary_text'],
117              theme_text_color='Custom' if is_enable else 'Primary',
118              text_color=ThemeClsColor,)
119          meny.canvas.children[3].rgba = \
120              self.canvas_color_black if is_enable else self.canvas_color
121          meny.add_widget(AvatarSampleWidget(
122              source=os.path.join(
123                  self.image_dir, "text_images", "{}.png".format(avatar_image_first_letter(
124                      item["text"].strip())))
125          ))
126          meny.bind(on_press=partial(
127              self.myadd_detail, item['secondary_text'], item['text']))
128          self.set_address_status(item, meny, is_enable)
129  
130      def set_address_status(self, item, meny, is_enable):
131          """Setting the identity status enable/disable on UI"""
132          if self.kivy_state.selected_address == item['secondary_text'] and is_enable:
133              meny.add_widget(self.is_active_badge())
134          else:
135              meny.add_widget(ToggleBtn(active=True if is_enable else False))
136          self.ids.ml.add_widget(meny)
137  
138      def set_mdList(self, first_index, last_index):
139          """Creating the mdlist"""
140          data = []
141          self.get_address_list(first_index, last_index, data)
142          for item in data:
143              self.set_address_to_widget(item)
144  
145      def check_scroll_y(self, instance, somethingelse):
146          """Load data on Scroll down"""
147          if self.ids.refresh_layout.scroll_y <= self.min_scroll_y_limit and self.has_refreshed:
148              self.ids.refresh_layout.scroll_y = self.scroll_y_step
149              my_addresses = len(self.ids.ml.children)
150              if my_addresses != len(self.addresses_list):
151                  self.update_addressBook_on_scroll(my_addresses)
152              self.has_refreshed = (
153                  True if my_addresses != len(self.addresses_list) else False
154              )
155  
156      def update_addressBook_on_scroll(self, my_addresses):
157          """Loads more data on scroll down"""
158          self.set_mdList(my_addresses, my_addresses + self.number_of_addresses)
159  
160      def myadd_detail(self, fromaddress, label, *args):
161          """Load myaddresses details"""
162          if config.getboolean(fromaddress, 'enabled'):
163              obj = MyaddDetailPopup()
164              self.address_label = obj.address_label = label
165              self.text_address = obj.address = fromaddress
166              width = self.is_android_width if platform == 'android' else self.other_platform_width
167              self.myadddetail_popup = self.myaddress_detail_popup(obj, width)
168              self.myadddetail_popup.auto_dismiss = False
169              self.myadddetail_popup.open()
170          else:
171              width = self.disabled_addr_width if platform == 'android' else self.other_platform_disabled_addr_width
172              self.dialog_box = self.inactive_address_popup(width, self.callback_for_menu_items)
173              self.dialog_box.open()
174  
175      def callback_for_menu_items(self, text_item, *arg):
176          """Callback of inactive address alert box"""
177          self.dialog_box.dismiss()
178          toast(text_item)
179  
180      def refresh_callback(self, *args):
181          """Method updates the state of application,
182          While the spinner remains on the screen"""
183          def refresh_callback(interval):
184              """Method used for loading the myaddress screen data"""
185              self.kivy_state.searching_text = ''
186              self.ids.search_bar.ids.search_field.text = ''
187              self.has_refreshed = True
188              self.ids.ml.clear_widgets()
189              self.init_ui()
190              self.ids.refresh_layout.refresh_done()
191              Clock.schedule_once(self.address_permision_callback, 0)
192          Clock.schedule_once(refresh_callback, 1)
193  
194      @staticmethod
195      def filter_address(address):
196          """It will return True if search is matched"""
197          searched_text = App.get_running_app().kivy_state_obj.searching_text.lower()
198          return bool(config.search_addresses(address, searched_text))
199  
200      def disable_address_ui(self, address, instance):
201          """This method is used to disable addresses from UI"""
202          config.disable_address(address)
203          instance.parent.parent.theme_text_color = 'Primary'
204          instance.parent.parent.canvas.children[3].rgba = MyAddress.canvas_color_gray
205          toast('Address disabled')
206          Clock.schedule_once(self.address_permision_callback, 0)
207  
208      def enable_address_ui(self, address, instance):
209          """This method is used to enable addresses from UI"""
210          config.enable_address(address)
211          instance.parent.parent.theme_text_color = 'Custom'
212          instance.parent.parent.canvas.children[3].rgba = MyAddress.canvas_color_black
213          toast('Address Enabled')
214          Clock.schedule_once(self.address_permision_callback, 0)
215  
216      def address_permision_callback(self, dt=0):
217          """callback for enable or disable addresses"""
218          addresses = [addr for addr in config.addresses()
219                       if config.getboolean(str(addr), 'enabled')]
220          self.parent.parent.ids.content_drawer.ids.identity_dropdown.values = addresses
221          self.parent.parent.ids.id_create.children[1].ids.composer_dropdown.values = addresses
222          self.kivy_running_app.identity_list = addresses
223  
224      def toggleAction(self, instance):
225          """This method is used for enable or disable address"""
226          addr = instance.parent.parent.secondary_text
227          if instance.active:
228              self.enable_address_ui(addr, instance)
229          else:
230              self.disable_address_ui(addr, instance)