From: Christian Heller Date: Fri, 25 Jul 2025 02:12:40 +0000 (+0200) Subject: Provide for sub-windows per connection client. X-Git-Url: https://plomlompom.com/repos/booking/%22https:/validator.w3.org/%7B%7Bdb.prefix%7D%7D/%7B%7Bprefix%7D%7D/balance2?a=commitdiff_plain;p=ircplom Provide for sub-windows per connection client. --- diff --git a/ircplom/irc_conn.py b/ircplom/irc_conn.py index af7cff4..192c096 100644 --- a/ircplom/irc_conn.py +++ b/ircplom/irc_conn.py @@ -221,7 +221,7 @@ class Client(ABC, ClientQueueMixin): Thread(target=connect, daemon=True, args=(self,)).start() @abstractmethod - def log(self, msg: str) -> None: + def log(self, msg: str, chat: str = '') -> None: 'Write msg into log, whatever shape that may have.' def send(self, msg: IrcMessage) -> None: @@ -293,3 +293,5 @@ class _RecvEvent(ClientEvent, PayloadMixin): target.close() elif msg.verb in {'001', 'NICK'}: target.update_login(nickname=msg.params[0], nick_confirmed=True) + elif msg.verb == 'PRIVMSG': + target.log(msg=str(msg.params), chat=msg.source) diff --git a/ircplom/tui.py b/ircplom/tui.py index fe5df12..49c6acb 100644 --- a/ircplom/tui.py +++ b/ircplom/tui.py @@ -430,6 +430,31 @@ class Tui(QueueMixin): 'Currently selected _Window.' return self.windows[self._window_idx] + def client_wins(self, client_id: UUID) -> list['_ClientWindow']: + 'All _ClientWindows matching client_id.' + return [win for win in self.windows + if isinstance(win, _ClientWindow) + and win.client_id == client_id] # pylint: disable=no-member + + def client_win(self, client_id: UUID, chat: str = '') -> '_ClientWindow': + '''That _ClientWindow matching client_id and chat; create if none. + + In case of creation, also switch to window, and if not client's first + window, copy prompt prefix from client's first window. + ''' + client_wins = self.client_wins(client_id) + candidates = [win for win in client_wins if win.chat == chat] + if candidates: + return candidates[0] + new_idx = len(self.windows) + win = _ClientWindow(idx=new_idx, term=self.term, q_out=self._q_out, + client_id=client_id, chat=chat) + if client_wins: + win.prompt.prefix = client_wins[0].prompt.prefix + self.windows += [win] + self._switch_window(new_idx) + return win + def log(self, msg: str) -> None: 'Post msg to active window\'s log.' self.window.log.append(msg) @@ -441,14 +466,9 @@ class Tui(QueueMixin): def cmd__connect(self, hostname: str, nickname: str, realname: str ) -> None: 'Create Client and pass it via NewClientEvent.' - client = _ClientKnowingTui(q_out=self._q_out, hostname=hostname, - nickname=nickname, realname=realname) - new_idx = len(self.windows) - self.windows += [_ClientWindow(idx=new_idx, term=self.term, - q_out=self._q_out, - client_id=client.id_)] - self._switch_window(new_idx) - self._put(NewClientEvent(client)) + self._put(NewClientEvent( + _ClientKnowingTui(q_out=self._q_out, hostname=hostname, + nickname=nickname, realname=realname))) def cmd__prompt_enter(self) -> None: 'Get prompt content from .window.prompt.enter, parse to & run command.' @@ -609,8 +629,9 @@ class Terminal(QueueMixin): class _ClientWindow(_Window, ClientQueueMixin): client_id_name = 'client_id' - def __init__(self, client_id: UUID, **kwargs) -> None: + def __init__(self, client_id: UUID, chat: str = '', **kwargs) -> None: self.client_id = client_id + self.chat = chat super().__init__(**kwargs) def cmd__disconnect(self, quit_msg: str = 'ircplom says bye') -> None: @@ -630,18 +651,16 @@ class _ClientWindow(_Window, ClientQueueMixin): class _ClientWindowEvent(TuiEvent, ClientIdMixin): - def client_win(self, target: Tui) -> _ClientWindow: - 'Identifies proper _ClientWindow in target TUI.' - return [win for win in target.windows - if isinstance(win, _ClientWindow) - and win.client_id == self.client_id][0] + def __init__(self, chat: str = '', **kwargs) -> None: + self.chat = chat + super().__init__(**kwargs) class _ClientLogEvent(_ClientWindowEvent, PayloadMixin): payload: str def affect(self, target: Tui) -> None: - self.client_win(target).log.append(self.payload) + target.client_win(self.client_id, self.chat).log.append(self.payload) super().affect(target) @@ -649,17 +668,19 @@ class _ClientPromptEvent(_ClientWindowEvent, PayloadMixin): payload: tuple[str, str] def affect(self, target: Tui) -> None: - prompt = self.client_win(target).prompt - prompt.prefix = ((' ' if self.payload[0] else '?') - + f'{self.payload[1]}{_PROMPT_TEMPLATE}') - prompt.tainted = True + new_prefix = ((' ' if self.payload[0] else '?') + + f'{self.payload[1]}{_PROMPT_TEMPLATE}') + for win in target.client_wins(self.client_id): + prompt = win.prompt + prompt.prefix = new_prefix + prompt.tainted = True super().affect(target) class _ClientKnowingTui(Client): - def log(self, msg: str) -> None: - self._cput(_ClientLogEvent, payload=msg) + def log(self, msg: str, chat: str = '') -> None: + self._cput(_ClientLogEvent, chat=chat, payload=msg) def update_login(self, nick_confirmed: bool, nickname: str = '') -> None: super().update_login(nick_confirmed, nickname)