/ src / bitmessagekivy / baseclass / msg_composer.py
msg_composer.py
  1  # pylint: disable=unused-argument, consider-using-f-string, too-many-ancestors
  2  # pylint: disable=no-member, no-name-in-module, too-few-public-methods, no-name-in-module
  3  """
  4      Message composer screen UI
  5  """
  6  
  7  import logging
  8  
  9  from kivy.app import App
 10  from kivy.properties import (
 11      BooleanProperty,
 12      ListProperty,
 13      NumericProperty,
 14      ObjectProperty,
 15  )
 16  from kivy.uix.behaviors import FocusBehavior
 17  from kivy.uix.boxlayout import BoxLayout
 18  from kivy.uix.label import Label
 19  from kivy.uix.recycleview import RecycleView
 20  from kivy.uix.recycleboxlayout import RecycleBoxLayout
 21  from kivy.uix.recycleview.layout import LayoutSelectionBehavior
 22  from kivy.uix.recycleview.views import RecycleDataViewBehavior
 23  from kivy.uix.screenmanager import Screen
 24  
 25  from kivymd.uix.textfield import MDTextField
 26  
 27  from pybitmessage import state
 28  from pybitmessage.bitmessagekivy.get_platform import platform
 29  from pybitmessage.bitmessagekivy.baseclass.common import (
 30      toast, kivy_state_variables, composer_common_dialog
 31  )
 32  
 33  logger = logging.getLogger('default')
 34  
 35  
 36  class Create(Screen):
 37      """Creates Screen class for kivy Ui"""
 38  
 39      def __init__(self, **kwargs):
 40          """Getting Labels and address from addressbook"""
 41          super(Create, self).__init__(**kwargs)
 42          self.kivy_running_app = App.get_running_app()
 43          self.kivy_state = kivy_state_variables()
 44          self.dropdown_widget = DropDownWidget()
 45          self.dropdown_widget.ids.txt_input.starting_no = 2
 46          self.add_widget(self.dropdown_widget)
 47          self.children[0].ids.id_scroll.bind(scroll_y=self.check_scroll_y)
 48  
 49      def check_scroll_y(self, instance, somethingelse):  # pylint: disable=unused-argument
 50          """show data on scroll down"""
 51          if self.children[1].ids.composer_dropdown.is_open:
 52              self.children[1].ids.composer_dropdown.is_open = False
 53  
 54  
 55  class RV(RecycleView):
 56      """Recycling View class for kivy Ui"""
 57  
 58      def __init__(self, **kwargs):
 59          """Recycling Method"""
 60          super(RV, self).__init__(**kwargs)
 61  
 62  
 63  class SelectableRecycleBoxLayout(
 64      FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout
 65  ):
 66      """Adds selection and focus behaviour to the view"""
 67      # pylint: disable = duplicate-bases
 68  
 69  
 70  class DropDownWidget(BoxLayout):
 71      """DropDownWidget class for kivy Ui"""
 72  
 73      # pylint: disable=too-many-statements
 74  
 75      txt_input = ObjectProperty()
 76      rv = ObjectProperty()
 77  
 78      def __init__(self, **kwargs):
 79          super(DropDownWidget, self).__init__(**kwargs)
 80          self.kivy_running_app = App.get_running_app()
 81          self.kivy_state = kivy_state_variables()
 82  
 83      @staticmethod
 84      def callback_for_msgsend(dt=0):  # pylint: disable=unused-argument
 85          """Callback method for messagesend"""
 86          state.kivyapp.root.ids.id_create.children[0].active = False
 87          state.in_sent_method = True
 88          state.kivyapp.back_press()
 89          toast("sent")
 90  
 91      def reset_composer(self):
 92          """Method will reset composer"""
 93          self.ids.ti.text = ""
 94          self.ids.composer_dropdown.text = "Select"
 95          self.ids.txt_input.text = ""
 96          self.ids.subject.text = ""
 97          self.ids.body.text = ""
 98          toast("Reset message")
 99  
100      def auto_fill_fromaddr(self):
101          """Fill the text automatically From Address"""
102          self.ids.ti.text = self.ids.composer_dropdown.text
103          self.ids.ti.focus = True
104  
105      def is_camara_attached(self):
106          """Checks the camera availability in device"""
107          self.parent.parent.parent.ids.id_scanscreen.check_camera()
108          is_available = self.parent.parent.parent.ids.id_scanscreen.camera_available
109          return is_available
110  
111      @staticmethod
112      def camera_alert():
113          """Show camera availability alert message"""
114          feature_unavailable = 'Currently this feature is not available!'
115          cam_not_available = 'Camera is not available!'
116          alert_text = feature_unavailable if platform == 'android' else cam_not_available
117          composer_common_dialog(alert_text)
118  
119  
120  class MyTextInput(MDTextField):
121      """MyTextInput class for kivy Ui"""
122  
123      txt_input = ObjectProperty()
124      flt_list = ObjectProperty()
125      word_list = ListProperty()
126      starting_no = NumericProperty(3)
127      suggestion_text = ''
128  
129      def __init__(self, **kwargs):
130          """Getting Text Input."""
131          super(MyTextInput, self).__init__(**kwargs)
132          self.__lineBreak__ = 0
133  
134      def on_text(self, instance, value):  # pylint: disable=unused-argument
135          """Find all the occurrence of the word"""
136          self.parent.parent.parent.parent.parent.ids.rv.data = []
137          max_recipient_len = 10
138          box_height = 250
139          box_max_height = 400
140  
141          matches = [self.word_list[i] for i in range(
142              len(self.word_list)) if self.word_list[
143                  i][:self.starting_no] == value[:self.starting_no]]
144          display_data = []
145          for i in matches:
146              display_data.append({'text': i})
147          self.parent.parent.parent.parent.parent.ids.rv.data = display_data
148          if len(matches) <= max_recipient_len:
149              self.parent.height = (box_height + (len(matches) * 20))
150          else:
151              self.parent.height = box_max_height
152  
153      def keyboard_on_key_down(self, window, keycode, text, modifiers):
154          """Keyboard on key Down"""
155          if self.suggestion_text and keycode[1] == 'tab' and modifiers is None:
156              self.insert_text(self.suggestion_text + ' ')
157              return True
158          return super(MyTextInput, self).keyboard_on_key_down(
159              window, keycode, text, modifiers)
160  
161  
162  class SelectableLabel(RecycleDataViewBehavior, Label):
163      """Add selection support to the Label"""
164  
165      index = None
166      selected = BooleanProperty(False)
167      selectable = BooleanProperty(True)
168  
169      def refresh_view_attrs(self, rv, index, data):
170          """Catch and handle the view changes"""
171          self.index = index
172          return super(SelectableLabel, self).refresh_view_attrs(rv, index, data)
173  
174      def on_touch_down(self, touch):  # pylint: disable=inconsistent-return-statements
175          """Add selection on touch down"""
176          if super(SelectableLabel, self).on_touch_down(touch):
177              return True
178          if self.collide_point(*touch.pos) and self.selectable:
179              return self.parent.select_with_touch(self.index, touch)
180  
181      def apply_selection(self, rv, index, is_selected):
182          """Respond to the selection of items in the view"""
183          self.selected = is_selected
184          if is_selected:
185              logger.debug("selection changed to %s", rv.data[index])
186              rv.parent.txt_input.text = rv.parent.txt_input.text.replace(
187                  rv.parent.txt_input.text, rv.data[index]["text"]
188              )