diff sat_frontends/quick_frontend/quick_chat.py @ 2880:dd650f3e070f

quick frontend(chat): prepared factorisation of merging of user moved info messages: - new MessageWidget class, to have a common ancestor for widgets from different frontends - new message_widgets_rev property to get reverse iterator on message widgets - new isUserMoved method to check if a Message is a user moved info - new handleUserMoved method to merge info message when suitable. This is code from Primitivus made generic.
author Goffi <goffi@goffi.org>
date Thu, 28 Mar 2019 08:39:19 +0100
parents 33a69ee7fbb7
children ca55e02a6fc8
line wrap: on
line diff
--- a/sat_frontends/quick_frontend/quick_chat.py	Wed Mar 27 21:15:25 2019 +0100
+++ b/sat_frontends/quick_frontend/quick_chat.py	Thu Mar 28 08:39:19 2019 +0100
@@ -211,6 +211,13 @@
                 self.message[lang] = u"* " + nick + mess[3:]
 
 
+class MessageWidget(object):
+    """Base classe for widgets"""
+    # This class does nothing and is only used to have a common ancestor
+
+    pass
+
+
 class Occupant(object):
     """Occupant metadata"""
 
@@ -366,6 +373,14 @@
     def contact_list(self):
         return self.host.contact_lists[self.profile]
 
+    @property
+    def message_widgets_rev(self):
+        """Return the history of MessageWidget in reverse chronological order
+
+        Must be implemented by frontend
+        """
+        raise NotImplementedError
+
     ## synchornisation handling ##
 
     @quick_widgets.QuickWidget.sync.setter
@@ -745,6 +760,58 @@
         """
         raise NotImplementedError
 
+    def isUserMoved(self, message):
+        """Return True if message is a user left/joined message
+
+        @param message(Message): message to check
+        @return (bool): True is message is user moved info message
+        """
+        if message.type != C.MESS_TYPE_INFO:
+            return False
+        try:
+            info_type = message.extra["info_type"]
+        except KeyError:
+            return False
+        else:
+            return info_type in ROOM_USER_MOVED
+
+    def handleUserMoved(self, message):
+        """Check if this message is a UserMoved one, and merge it when possible
+
+        "merge it" means that info message indicating a user joined/left will be
+        grouped if no other non-info messages has been sent since
+        @param message(Message): message to check
+        @return (bool): True if this message has been merged
+            if True, a new MessageWidget must not be created and appended to history
+        """
+        if self.isUserMoved(message):
+            for wid in self.message_widgets_rev:
+                # we merge in/out messages if no message was sent meanwhile
+                if not isinstance(wid, MessageWidget):
+                    continue
+                elif wid.mess_data.type != C.MESS_TYPE_INFO:
+                    return False
+                elif (
+                    wid.info_type in ROOM_USER_MOVED
+                    and wid.mess_data.nick == message.nick
+                ):
+                    try:
+                        count = wid.reentered_count
+                    except AttributeError:
+                        count = wid.reentered_count = 1
+                    nick = wid.mess_data.nick
+                    if message.info_type == ROOM_USER_LEFT:
+                        wid.message = _(u"<= {nick} has left the room ({count})").format(
+                            nick=nick, count=count
+                        )
+                    else:
+                        wid.message = _(
+                            u"<=> {nick} re-entered the room ({count})"
+                        ).format(nick=nick, count=count)
+                        wid.reentered_count += 1
+                    return True
+        return False
+
     def printDayChange(self, day):
         """Display the day on a new line.