diff sat_frontends/quick_frontend/quick_chat.py @ 2849:c2858e63cd82

quick frontend(chat): added setLocked/setUnlocked methods: those methods replace manual change of self._locked and manual creation/handling of caching.
author Goffi <goffi@goffi.org>
date Sun, 10 Mar 2019 18:02:58 +0100
parents c055a3a4ecb0
children 272dc905ff20
line wrap: on
line diff
--- a/sat_frontends/quick_frontend/quick_chat.py	Sun Mar 10 18:02:56 2019 +0100
+++ b/sat_frontends/quick_frontend/quick_chat.py	Sun Mar 10 18:02:58 2019 +0100
@@ -276,13 +276,12 @@
         """
         self.lang = ""  # default language to use for messages
         quick_widgets.QuickWidget.__init__(self, host, target, profiles=profiles)
-        self._locked = True  # True when we are waiting for history/search
-        # messageNew signals are cached when locked
-        self._cache = OrderedDict()
         assert type_ in (C.CHAT_ONE2ONE, C.CHAT_GROUP)
         self.current_target = target
         self.type = type_
         self.encrypted = False  # True if this session is currently encrypted
+        self._locked = False
+        self.setLocked()
         if type_ == C.CHAT_GROUP:
             if target.resource:
                 raise exceptions.InternalError(
@@ -317,6 +316,34 @@
         if self.host.AVATARS_HANDLER:
             self.host.addListener("avatar", self.onAvatar, profiles)
 
+    def setLocked(self):
+        """Set locked flag
+
+        To be set when we are waiting for history/search
+        """
+        # FIXME: we don't use getter/setter here because of pyjamas
+        # TODO: use proper getter/setter once we get rid of pyjamas
+        if self._locked:
+            log.warning(u"{wid} is already locked!".format(wid=self))
+            return
+        self._locked = True
+        # messageNew signals are cached when locked
+        self._cache = OrderedDict()
+        log.debug(u"{wid} is now locked".format(wid=self))
+
+    def setUnlocked(self):
+        if not self._locked:
+            log.debug(u"{wid} was already unlocked".format(wid=self))
+            return
+        self._locked = False
+        for uid, data in self._cache.iteritems():
+            if uid not in self.messages:
+                self.messageNew(*data)
+            else:
+                log.debug(u"discarding message already in history: {data}, ".format(data=data))
+        del self._cache
+        log.debug(u"{wid} is now unlocked".format(wid=self))
+
     def postInit(self):
         """Method to be called by frontend after widget is initialised
 
@@ -462,8 +489,7 @@
         @param filters (str): patterns to filter the history results
         @param profile (str): %(doc_profile)s
         """
-        self._locked = True
-        self._cache = OrderedDict()
+        self.setLocked()
         self.messages.clear()
         self.historyPrint(size, filters, profile)
 
@@ -473,14 +499,12 @@
         unlock the widget, and can be used to refresh or scroll down
         the focus after the history is printed
         """
-        self._locked = False
-        for data in self._cache.itervalues():
-            self.messageNew(*data)
-        del self._cache
+        self.setUnlocked()
 
     def historyPrint(self, size=C.HISTORY_LIMIT_DEFAULT, filters=None, profile="@NONE@"):
         """Print the current history
 
+        Note: self.setUnlocked will be called once history is printed
         @param size (int): number of messages
         @param search (str): pattern to filter the history results
         @param profile (str): %(doc_profile)s
@@ -524,10 +548,6 @@
             #     previous_day = message_day
             for data in history:
                 uid, timestamp, from_jid, to_jid, message, subject, type_, extra = data
-                # cached messages may already be in history
-                # so we check it to avoid duplicates, they'll be added later
-                if uid in self._cache:
-                    continue
                 from_jid = jid.JID(from_jid)
                 to_jid = jid.JID(to_jid)
                 # if ((self.type == C.CHAT_GROUP and type_ != C.MESS_TYPE_GROUPCHAT) or