home · contact · privacy
Overhaul nickname display updates, only show in _PrivmsgPromptWidget. master
authorChristian Heller <c.heller@plomlompom.de>
Wed, 6 Aug 2025 14:59:44 +0000 (16:59 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 6 Aug 2025 14:59:44 +0000 (16:59 +0200)
ircplom/client_tui.py

index 79992b9437101d205bafc66bfd9881b157b34f11..fe49e214bc27b813ba1e78f45d4852b6b56dd992 100644 (file)
@@ -2,7 +2,7 @@
 # built-ins
 from dataclasses import dataclass
 from getpass import getuser
-from typing import Optional
+from typing import Any, Optional
 # ourselves
 from ircplom.tui_base import (BaseTui, PromptWidget, TuiEvent, Window,
                               CMD_SHORTCUTS)
@@ -15,26 +15,10 @@ CMD_SHORTCUTS['nick'] = 'window.nick'
 CMD_SHORTCUTS['privmsg'] = 'window.privmsg'
 CMD_SHORTCUTS['reconnect'] = 'window.reconnect'
 
-
-class _ClientPromptWidget(PromptWidget):
-    _prefix: str = ''
-
-    @property
-    def prefix(self) -> str:
-        return self._prefix + super().prefix
-
-    @prefix.setter
-    def prefix(self, to_set: str) -> None:
-        self._prefix = to_set
-        self.tainted = True
-
-    def prefix_copy_to(self, other: '_ClientPromptWidget') -> None:
-        'Copy over .prefix to other.'
-        other.prefix = self._prefix
+_PROMPT_UPDATE_TRIGGER_KEYS = {'nick_confirmed', 'nickname'}
 
 
 class _ClientWindow(Window, ClientQueueMixin):
-    prompt: _ClientPromptWidget
 
     def __init__(self, chat: str = '', **kwargs) -> None:
         self.chat = chat
@@ -65,7 +49,17 @@ class _ClientWindow(Window, ClientQueueMixin):
                        chat=target, to_log=f'>[MYSELF] {msg}')
 
 
-class _PrivmsgPromptWidget(_ClientPromptWidget):
+class _PrivmsgPromptWidget(PromptWidget):
+    _prefix: str = ''
+
+    @property
+    def prefix(self) -> str:
+        return self._prefix + super().prefix
+
+    def update_prefix(self, nick_confirmed: bool, nickname: str) -> None:
+        'Update prompt prefix with nickname data.'
+        self._prefix = (' ' if nick_confirmed else '?') + nickname
+        self.tainted = True
 
     def enter(self) -> str:
         to_return = super().enter()
@@ -85,6 +79,10 @@ class _PrivmsgWindow(_ClientWindow):
 class ClientTui(BaseTui):
     'TUI expanded towards Client features.'
 
+    def __init__(self, **kwargs) -> None:
+        super().__init__(**kwargs)
+        self.clients_data: dict[str, dict[str, Any]] = {}
+
     def _new_client_window(self, client_id: str, chat: str = ''
                            ) -> _ClientWindow:
         new_idx = len(self._windows)
@@ -92,6 +90,9 @@ class ClientTui(BaseTui):
                      else _ClientWindow)
         win = win_class(idx=new_idx, term=self._term, _q_out=self._q_out,
                         client_id=client_id, chat=chat)
+        if isinstance(win, _PrivmsgWindow):
+            win.prompt.update_prefix(**{k: self.clients_data[client_id][k]
+                                        for k in _PROMPT_UPDATE_TRIGGER_KEYS})
         self._windows += [win]
         self._switch_window(new_idx)
         return win
@@ -108,17 +109,12 @@ class ClientTui(BaseTui):
         return wins
 
     def client_win(self, client_id: str, chat: str = '') -> _ClientWindow:
-        '''That _ClientWindow matching client_id and chat; create if none.
-
-        In case of creation, copy prompt prefix from client's first window.
-        '''
+        'That _ClientWindow matching client_id and chat; if none, create one.'
         client_wins = self.client_wins(client_id)
         candidates = [win for win in client_wins if win.chat == chat]
         if candidates:
             return candidates[0]
         win = self._new_client_window(client_id=client_id, chat=chat)
-        if client_wins:
-            client_wins[0].prompt.prefix_copy_to(win.prompt)
         return win
 
     def cmd__connect(self,
@@ -166,13 +162,21 @@ class _ClientLogEvent(TuiEvent, ClientIdMixin):
 
 
 @dataclass
-class _ClientPromptEvent(TuiEvent, ClientIdMixin):
-    payload: tuple[str, str]
+class _ClientDataEvent(TuiEvent, ClientIdMixin):
+    _updates: dict[str, Any]
 
     def affect(self, target: ClientTui) -> None:
-        new_prefix = (' ' if self.payload[0] else '?') + self.payload[1]
-        for win in target.client_wins(self.client_id):
-            win.prompt.prefix = new_prefix
+        if self.client_id not in target.clients_data:
+            target.clients_data[self.client_id] = {}
+        clients_data = target.clients_data[self.client_id]
+        for k, v in self._updates.items():
+            clients_data[k] = v
+        if _PROMPT_UPDATE_TRIGGER_KEYS & set(self._updates.keys()):
+            for prompt in [w.prompt for w in target.client_wins(self.client_id)
+                           if isinstance(w.prompt, _PrivmsgPromptWidget)]:
+                assert isinstance(prompt, _PrivmsgPromptWidget)
+                prompt.update_prefix(**{k: clients_data[k]
+                                        for k in _PROMPT_UPDATE_TRIGGER_KEYS})
         target.redraw_affected()
 
 
@@ -183,5 +187,6 @@ class _ClientKnowingTui(Client):
 
     def update_login(self, nick_confirmed: bool, nickname: str = '') -> None:
         super().update_login(nick_confirmed, nickname)
-        self._cput(_ClientPromptEvent,
-                   payload=(self.nick_confirmed, self.conn_setup.nickname))
+        self._cput(_ClientDataEvent,
+                   _updates={'nick_confirmed': self.nick_confirmed,
+                             'nickname': self.conn_setup.nickname})