home · contact · privacy
Fix broken forwarding of updates/messages into proper chat windows.
authorChristian Heller <c.heller@plomlompom.de>
Mon, 18 Aug 2025 18:04:54 +0000 (20:04 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Mon, 18 Aug 2025 18:04:54 +0000 (20:04 +0200)
ircplom/client.py
ircplom/client_tui.py

index 72e00fddeef31afd123c95fcba4931e188459eec..16e935a9baa9871f001918997f37fc89f1880942 100644 (file)
@@ -347,9 +347,22 @@ class _Db(Db):
     def _completable_key(key):
         return f'_completable_{key}'
 
-    def append_completable(self, key: str, value: str) -> None:
+    def _on_completable(self, method: str, key: str, value: str, stay_complete
+                        ) -> None:
+        completable = getattr(self, self._completable_key(key))
+        getattr(completable, method)(value, stay_complete)
+        if stay_complete:
+            self._on_update(key)
+
+    def append_completable(self, key: str, value: str, stay_complete=False
+                           ) -> None:
         'To completable list of key append value.'
-        getattr(self, self._completable_key(key)).append(value)
+        self._on_completable('append', key, value, stay_complete)
+
+    def remove_completable(self, key: str, value: str, stay_complete=False
+                           ) -> None:
+        'From completable list of key remove value.'
+        self._on_completable('remove', key, value, stay_complete)
 
     def declare_complete(self, key: str) -> None:
         'Declare completable at key complete.'
@@ -562,7 +575,7 @@ class Client(ABC, ClientQueueMixin):
             self.set_nick(msg.params[0], confirmed=True)
         elif msg.match('NOTICE', 2) or msg.match('PRIVMSG', 2):
             scope = LogScope.CHAT if '!' in msg.source else LogScope.SERVER
-            self._log(msg.params[-1], scope=scope, channel=msg.params[0],
+            self._log(msg.params[-1], scope=scope, target=msg.params[0],
                       out=False, as_notice=msg.verb == 'NOTICE',
                       sender=msg.nick_from_source)
         elif msg.match('PART', len_is_min=True) or msg.match('JOIN'):
@@ -570,13 +583,16 @@ class Client(ABC, ClientQueueMixin):
             log_msg = f'{msg.nick_from_source} {msg.verb.lower()}s {channel}'
             if msg.match('PART', 2, True):
                 log_msg += f': {msg.params[1]}'
-            self._log(log_msg, scope=LogScope.CHAT, channel=channel)
+            self._log(log_msg, scope=LogScope.CHAT, target=channel)
             if msg.verb == 'JOIN':
-                self._db.chan(channel).users.append(msg.nick_from_source)
+                if msg.nick_from_source != self._db.nickname:
+                    self._db.chan(channel).append_completable(
+                            'users', msg.nick_from_source, stay_complete=True)
             elif msg.nick_from_source == self._db.nickname:
                 self._db.del_chan(channel)
             else:
-                self._db.chan(channel).users.remove(msg.nick_from_source)
+                self._db.chan(channel).remove_completable(
+                        'users', msg.nick_from_source, stay_complete=True)
         elif msg.match('PING'):
             self.send(IrcMessage(verb='PONG', params=(msg.params[0],)))
         else:
index 84823a4d96d95ac377d18440e458a85f29537d60..b032106ece260c4f7989cfae14d9316e6c9cb3f1 100644 (file)
@@ -199,7 +199,7 @@ class _ClientWindowsManager:
     _tui_new_window: Callable
 
     def __post_init__(self, *_, **__) -> None:
-        self._db = _TuiClientDb()
+        self.db = _TuiClientDb()
         self.windows: list[_ClientWindow] = []
         for scope in (LogScope.SERVER, LogScope.RAW):
             self._new_win(scope)
@@ -210,7 +210,7 @@ class _ClientWindowsManager:
             kwargs['win_cls'] = (_ChannelWindow if chatname[0] == '#'
                                  else _ChatWindow)
             kwargs['chatname'] = chatname
-            kwargs['get_nick_data'] = lambda: (self._db.nickname,)
+            kwargs['get_nick_data'] = lambda: (self.db.nickname,)
         win = self._tui_new_window(**kwargs)
         self.windows += [win]
         return win
@@ -232,7 +232,7 @@ class _ClientWindowsManager:
         if 'out' in kwargs and scope != LogScope.SERVER:
             first_char = _LOG_PREFIX_OUT if kwargs['out'] else _LOG_PREFIX_IN
             if scope == LogScope.CHAT:
-                sender_label = ' [' + (self._db.nickname if kwargs['out']
+                sender_label = ' [' + (self.db.nickname if kwargs['out']
                                        else kwargs['sender']) + ']'
         if kwargs.get('as_notice', False):
             first_char *= 3
@@ -240,14 +240,14 @@ class _ClientWindowsManager:
         self._tui_log(msg, scope=scope, prefix=prefix, **kwargs)
 
     def update_db(self, update: _Update) -> bool:
-        'Apply update to ._db, and if changing anything, log and trigger.'
+        'Apply update to .db, and if changing anything, log and trigger.'
         scope = (LogScope.CHAT if update.is_chan
                  else (LogScope.ALL if update.path == 'connection_state'
                        else LogScope.SERVER))
         verb = 'cleared' if update.value is None else 'changed to:'
         what = f'{update.path}:{update.arg}' if update.arg else update.path
-        log_kwargs = {'channel': update.path} if update.is_chan else {}
-        if not self._db.set_and_check_for_change(update):
+        log_kwargs = {'target': update.path} if update.is_chan else {}
+        if not self.db.set_and_check_for_change(update):
             return False
         announcement = f'{what} {verb}'
         if isinstance(update.value, tuple) or announcement[-1] != ':':
@@ -271,18 +271,19 @@ class ClientTui(BaseTui):
         self._client_mngrs: dict[str, _ClientWindowsManager] = {}
 
     def _log_target_wins(self, **kwargs) -> Sequence[Window]:
-        target = kwargs.get('scope', LogScope.SAME)
-        if target != LogScope.SAME:
+        scope = kwargs.get('scope', LogScope.SAME)
+        if scope != LogScope.SAME:
             m = self._client_mngrs[kwargs['client_id']]
-            if target == LogScope.ALL:
+            if scope == LogScope.ALL:
                 return m.windows
-            if target == LogScope.SERVER:
+            if scope == LogScope.SERVER:
                 return [m.window(LogScope.SERVER), m.window(LogScope.RAW)]
-            if target == LogScope.CHAT:
-                chatname = (kwargs['target'] if kwargs.get('out', False)
-                            else kwargs.get('sender', kwargs['channel']))
+            if scope == LogScope.CHAT:
+                chatname = (
+                        kwargs['target'] if kwargs['target'] != m.db.nickname
+                        else kwargs['sender'])
                 return [m.window(LogScope.CHAT, chatname=chatname)]
-            return [m.window(target)]
+            return [m.window(scope)]
         return super()._log_target_wins(**kwargs)
 
     def for_client_do(self, client_id: str, todo: str, **kwargs) -> None: