diff cagou/plugins/plugin_wid_chat.py @ 325:5868a5575e01

chat: cleaning + some improvments: - code cleaning, removed some dead code - some improvments on the way size is calculated, removed unnecessary sizing methods which were linked to properties - image have now a max size, this avoid gigantic image in the whole screen - in SimpleXHTMLWidget, Label are now splitted when xhtml is set - use a DelayedBoxLayout for messages, as they are really slow to be resized - use of RecycleView has been investigated, but it is not currently usable as dynamic contents are not propertly handled (see https://github.com/kivy/kivy/issues/6580 and https://github.com/kivy/kivy/issues/6582). Furthermore, some tests with RecycleView on Android don't give the expected speed boost, so BoxLayout still seems like the way to go for the moment. To be re-investigated at a later point if necessary.
author Goffi <goffi@goffi.org>
date Fri, 06 Dec 2019 13:25:31 +0100
parents e2b51663d8b8
children d9d2b56f46db
line wrap: on
line diff
--- a/cagou/plugins/plugin_wid_chat.py	Fri Dec 06 13:23:03 2019 +0100
+++ b/cagou/plugins/plugin_wid_chat.py	Fri Dec 06 13:25:31 2019 +0100
@@ -1,5 +1,4 @@
 #!/usr/bin/python
-# -*- coding: utf-8 -*-
 
 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client
 # Copyright (C) 2016-2019 Jérôme Poisson (goffi@goffi.org)
@@ -21,27 +20,27 @@
 from functools import partial
 import mimetypes
 import sys
-from sat.core import log as logging
-from sat.core.i18n import _
-from sat.core import exceptions
-from cagou.core.constants import Const as C
 from kivy.uix.boxlayout import BoxLayout
-from kivy.uix.gridlayout import GridLayout
 from kivy.uix.textinput import TextInput
 from kivy.metrics import sp, dp
 from kivy.clock import Clock
 from kivy import properties
+from kivy.uix.dropdown import DropDown
+from kivy.core.window import Window
+from sat.core import log as logging
+from sat.core.i18n import _
+from sat.core import exceptions
 from sat_frontends.quick_frontend import quick_widgets
 from sat_frontends.quick_frontend import quick_chat
 from sat_frontends.tools import jid
+from cagou import G
+from cagou.core.constants import Const as C
 from cagou.core import cagou_widget
 from cagou.core import xmlui
 from cagou.core.image import Image
 from cagou.core.common import SymbolButton, JidButton
-from kivy.uix.dropdown import DropDown
-from kivy.core.window import Window
-from cagou import G
 from cagou.core import menu
+# from random import randrange
 
 log = logging.getLogger(__name__)
 
@@ -73,63 +72,64 @@
     pass
 
 
-class MessageWidget(BoxLayout, quick_chat.MessageWidget):
+class MessageWidget(quick_chat.MessageWidget, BoxLayout):
     mess_data = properties.ObjectProperty()
     mess_xhtml = properties.ObjectProperty()
     mess_padding = (dp(5), dp(5))
     avatar = properties.ObjectProperty()
     delivery = properties.ObjectProperty()
     font_size = properties.NumericProperty(sp(12))
+    right_part = properties.ObjectProperty()
+    header_box = properties.ObjectProperty()
 
-    def __init__(self, **kwargs):
-        # self must be registered in widgets before kv is parsed
-        kwargs['mess_data'].widgets.add(self)
-        super(MessageWidget, self).__init__(**kwargs)
-        avatar_path = self.mess_data.avatar
-        if avatar_path is not None:
-            self.avatar.source = avatar_path
+    def on_mess_data(self, wid, mess_data):
+        mess_data.widgets.add(self)
 
     @property
     def chat(self):
         """return parent Chat instance"""
         return self.mess_data.parent
 
+    def _get_from_mess_data(self, name, default):
+        if self.mess_data is None:
+            return default
+        return getattr(self.mess_data, name)
+
     def _get_message(self):
         """Return currently displayed message"""
+        if self.mess_data is None:
+            return ""
         return self.mess_data.main_message
 
     def _set_message(self, message):
+        if self.mess_data is None:
+            return False
         if message == self.mess_data.message.get(""):
             return False
         self.mess_data.message = {"": message}
         return True
 
-    message = properties.AliasProperty(_get_message, _set_message)
-
-    @property
-    def message_xhtml(self):
-        """Return currently displayed message"""
-        return self.mess_data.main_message_xhtml
+    message = properties.AliasProperty(
+        partial(_get_from_mess_data, name="main_message", default=""),
+        _set_message,
+        bind=['mess_data'],
+    )
+    message_xhtml = properties.AliasProperty(
+        partial(_get_from_mess_data, name="main_message_xhtml", default=""),
+        bind=['mess_data'])
+    mess_type = properties.AliasProperty(
+        partial(_get_from_mess_data, name="type", default=""), bind=['mess_data'])
+    own_mess = properties.AliasProperty(
+        partial(_get_from_mess_data, name="own_mess", default=False), bind=['mess_data'])
+    nick = properties.AliasProperty(
+        partial(_get_from_mess_data, name="nick", default=""), bind=['mess_data'])
+    time_text = properties.AliasProperty(
+        partial(_get_from_mess_data, name="time_text", default=""), bind=['mess_data'])
 
     @property
     def info_type(self):
         return self.mess_data.info_type
 
-    def widthAdjust(self):
-        """this widget grows up with its children"""
-        pass
-        # parent = self.mess_xhtml.parent
-        # padding_x = self.mess_padding[0]
-        # text_width, text_height = self.mess_xhtml.texture_size
-        # if text_width > parent.width:
-        #     self.mess_xhtml.text_size = (parent.width - padding_x, None)
-        #     self.text_max = text_width
-        # elif self.mess_xhtml.text_size[0] is not None and text_width  < parent.width - padding_x:
-        #     if text_width < self.text_max:
-        #         self.mess_xhtml.text_size = (None, None)
-        #     else:
-        #         self.mess_xhtml.text_size = (parent.width  - padding_x, None)
-
     def update(self, update_dict):
         if 'avatar' in update_dict:
             self.avatar.source = update_dict['avatar']
@@ -175,10 +175,6 @@
         self.dispatch('on_text_validate')
 
 
-class MessagesWidget(GridLayout):
-    pass
-
-
 class TransferButton(SymbolButton):
     chat = properties.ObjectProperty()
 
@@ -426,8 +422,8 @@
         self.extra_menu = ExtraMenu(chat=self)
         extra_btn = ExtraButton(chat=self)
         self.headerInputAddExtra(extra_btn)
-        self.header_input.hint_text = "{}".format(target)
-        self.postInit()
+        self.header_input.hint_text = target
+        Clock.schedule_once(lambda dt: self.postInit(), 0)
 
     def __str__(self):
         return "Chat({})".format(self.target)