# 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)
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
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()
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)
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
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,
@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()
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})