Clean up room widget and add nick list
This commit is contained in:
parent
d3cd63b67e
commit
d7f6d5a536
1 changed files with 88 additions and 50 deletions
|
|
@ -1,8 +1,8 @@
|
|||
import asyncio
|
||||
from enum import Enum
|
||||
from typing import Any, Awaitable, Callable, List, Optional, Tuple, TypeVar
|
||||
|
||||
import urwid
|
||||
|
||||
import yaboli
|
||||
|
||||
from ..attributed_text_widget import ATWidget
|
||||
|
|
@ -14,6 +14,7 @@ from ..markup import AT, AttributedText, Attributes
|
|||
from .edit_widgets import EditWidget
|
||||
from .euph_config import EuphConfig
|
||||
from .euph_renderer import EuphRenderer
|
||||
from .nick_list_widget import NickListWidget
|
||||
|
||||
__all__ = ["RoomWidget"]
|
||||
|
||||
|
|
@ -129,23 +130,33 @@ class RoomLayout(urwid.WidgetWrap):
|
|||
string = self._edit_separator * tree_width
|
||||
return AT(string, attributes=self._border_attrs)
|
||||
|
||||
def set_edit_visible(self, visible: bool):
|
||||
def set_edit_visible(self, visible: bool) -> None:
|
||||
if visible:
|
||||
self._left_wrap._w = self._edit_pile
|
||||
else:
|
||||
self._left_wrap._w = self._tree
|
||||
|
||||
def focus_on_edit(self):
|
||||
def focus_on_edit(self) -> None:
|
||||
self._edit_pile.focus_position = 2
|
||||
self._columns.focus_position = 0
|
||||
|
||||
def focus_on_tree(self):
|
||||
def focus_on_tree(self) -> None:
|
||||
self._edit_pile.focus_position = 0
|
||||
self._columns.focus_position = 0
|
||||
|
||||
def focus_on_user_list(self):
|
||||
def focus_on_nick_list(self) -> None:
|
||||
self._columns.focus_position = 2
|
||||
|
||||
class UiMode(Enum):
|
||||
|
||||
CONNECTING = "connecting"
|
||||
CONNECTION_FAILED = "connection failed"
|
||||
SETTING_PASSWORD = "setting password"
|
||||
AUTHENTICATING = "authenticating"
|
||||
SETTING_NICK = "setting nick"
|
||||
VIEWING = "viewing"
|
||||
EDITING = "editing"
|
||||
|
||||
class RoomWidget(urwid.WidgetWrap):
|
||||
"""
|
||||
The RoomWidget connects to and displays a single yaboli room.
|
||||
|
|
@ -159,11 +170,6 @@ class RoomWidget(urwid.WidgetWrap):
|
|||
event
|
||||
"""
|
||||
|
||||
CONNECTING = "connecting"
|
||||
CONNECTION_FAILED = "connection_failed"
|
||||
VIEWING = "viewing"
|
||||
EDITING = "editing"
|
||||
|
||||
def __init__(self,
|
||||
roomname: str,
|
||||
config: EuphConfig,
|
||||
|
|
@ -172,17 +178,24 @@ class RoomWidget(urwid.WidgetWrap):
|
|||
|
||||
self.c = config
|
||||
|
||||
if log_amount < 1:
|
||||
raise ValueError() # TODO add better text
|
||||
self._log_amount = log_amount
|
||||
if self._log_amount < 1:
|
||||
raise ValueError("log request amount must be at least 1")
|
||||
|
||||
self._mode: str
|
||||
self._mode: UiMode
|
||||
self._requesting_logs = False
|
||||
self._hit_top_of_supply = False
|
||||
|
||||
self._room = yaboli.Room(roomname)
|
||||
|
||||
self._room.register_event("connected", self.on_connected)
|
||||
self._room.register_event("snapshot", self.on_snapshot)
|
||||
self._room.register_event("send", self.on_send)
|
||||
self._room.register_event("join", self.on_join)
|
||||
self._room.register_event("part", self.on_part)
|
||||
self._room.register_event("nick", self.on_nick)
|
||||
self._room.register_event("edit", self.on_edit)
|
||||
self._room.register_event("disconnect", self.on_disconnect)
|
||||
|
||||
self._supply = InMemorySupply[Message]()
|
||||
self._renderer = self._create_euph_renderer()
|
||||
|
|
@ -297,7 +310,12 @@ class RoomWidget(urwid.WidgetWrap):
|
|||
return urwid.Edit(multiline=True)
|
||||
|
||||
def _create_nick_list_widget(self) -> Any:
|
||||
return urwid.SolidFill("n")
|
||||
return NickListWidget(
|
||||
heading_attrs={"style": self.c.nick_list_heading_style},
|
||||
counter_attrs={"style": self.c.nick_list_counter_style},
|
||||
nick_attrs={"style": self.c.nick_style},
|
||||
own_nick_attrs={"style": self.c.own_nick_style},
|
||||
)
|
||||
|
||||
def _create_room_layout_widget(self,
|
||||
room_name: Any,
|
||||
|
|
@ -336,50 +354,42 @@ class RoomWidget(urwid.WidgetWrap):
|
|||
|
||||
## UI mode and mode switching
|
||||
|
||||
CONNECTING = "connecting"
|
||||
CONNECTION_FAILED = "connection_failed"
|
||||
SETTING_PASSWORD = "setting_password"
|
||||
AUTHENTICATING = "authenticating"
|
||||
SETTING_NICK = "setting_nick"
|
||||
VIEWING = "viewing"
|
||||
EDITING = "editing"
|
||||
|
||||
def switch_connecting(self) -> None:
|
||||
self._w = self._connecting
|
||||
self._mode = self.CONNECTING
|
||||
self._mode = UiMode.CONNECTING
|
||||
|
||||
def switch_connection_failed(self) -> None:
|
||||
self._w = self._connection_failed
|
||||
self._mode = self.CONNECTION_FAILED
|
||||
self._mode = UiMode.CONNECTION_FAILED
|
||||
|
||||
def switch_setting_password(self) -> None:
|
||||
self._w = self._overlay
|
||||
self._overlay.set_top(self._edit_password)
|
||||
self._mode = self.SETTING_PASSWORD
|
||||
self._mode = UiMode.SETTING_PASSWORD
|
||||
|
||||
def switch_authenticating(self) -> None:
|
||||
self._w = self._overlay
|
||||
self._overlay.set_top(self._authenticating)
|
||||
self._mode = self.AUTHENTICATING
|
||||
self._mode = UiMode.AUTHENTICATING
|
||||
|
||||
def switch_setting_nick(self) -> None:
|
||||
self._w = self._overlay
|
||||
self._box.original_widget = self._edit_nick
|
||||
self._edit_nick.text = self._room.session.nick
|
||||
self.update_edit_nick()
|
||||
self._mode = self.SETTING_NICK
|
||||
self._mode = UiMode.SETTING_NICK
|
||||
|
||||
def switch_view(self) -> None:
|
||||
self._w = self._layout
|
||||
self._layout.set_edit_visible(False)
|
||||
self._layout.focus_on_tree()
|
||||
self._mode = self.VIEWING
|
||||
self._mode = UiMode.VIEWING
|
||||
|
||||
def switch_edit(self) -> None:
|
||||
self._w = self._layout
|
||||
self._layout.set_edit_visible(True)
|
||||
self._layout.focus_on_edit()
|
||||
self._mode = self.EDITING
|
||||
self._mode = UiMode.EDITING
|
||||
|
||||
# Updating various parts of the UI
|
||||
|
||||
|
|
@ -388,12 +398,15 @@ class RoomWidget(urwid.WidgetWrap):
|
|||
|
||||
def update_nick_list(self) -> None:
|
||||
# Ensure that self._room.session and self._room.users exist
|
||||
if self._mode not in {self.SETTING_NICK, self.VIEWING, self.EDITING}:
|
||||
allowed = {UiMode.SETTING_NICK, UiMode.VIEWING, UiMode.EDITING}
|
||||
if self._mode not in allowed:
|
||||
return
|
||||
|
||||
#self._nick_list.update(self._room.session, self._room.users)
|
||||
# Automatically rerenders
|
||||
self._nick_list.session = self._room.session
|
||||
self._nick_list.users = self._room.users
|
||||
|
||||
def update_edit_nick(self):
|
||||
def update_edit_nick(self) -> None:
|
||||
width = self._edit_nick.width
|
||||
self._overlay.set_overlay_parameters(
|
||||
align=urwid.CENTER,
|
||||
|
|
@ -403,15 +416,15 @@ class RoomWidget(urwid.WidgetWrap):
|
|||
)
|
||||
self._overlay._invalidate()
|
||||
|
||||
# Reacting to changes
|
||||
|
||||
def own_nick_change(self):
|
||||
def change_own_nick(self) -> None:
|
||||
self._renderer.nick = self._room.session.nick
|
||||
self._tree.invalidate_all()
|
||||
self.update_tree()
|
||||
|
||||
self._nick_list.session = self._room.session
|
||||
self.update_nick_list()
|
||||
|
||||
def receive_message(self, msg: yaboli.Message):
|
||||
def receive_message(self, msg: yaboli.Message) -> None:
|
||||
self._supply.add(Message(
|
||||
msg.message_id,
|
||||
msg.parent_id,
|
||||
|
|
@ -434,7 +447,7 @@ class RoomWidget(urwid.WidgetWrap):
|
|||
return canvas
|
||||
|
||||
def keypress(self, size: Tuple[int, int], key: str) -> Optional[str]:
|
||||
if self._mode == self.VIEWING:
|
||||
if self._mode == UiMode.VIEWING:
|
||||
if key in {"enter", "meta enter"} and not self._room.session.nick:
|
||||
self.switch_setting_nick()
|
||||
elif key == "enter":
|
||||
|
|
@ -452,7 +465,7 @@ class RoomWidget(urwid.WidgetWrap):
|
|||
else:
|
||||
return super().keypress(size, key)
|
||||
|
||||
elif self._mode == self.EDITING:
|
||||
elif self._mode == UiMode.EDITING:
|
||||
if key == "enter":
|
||||
if self._edit.edit_text:
|
||||
self.send(self._edit.edit_text, self._tree.cursor_id)
|
||||
|
|
@ -464,7 +477,7 @@ class RoomWidget(urwid.WidgetWrap):
|
|||
else:
|
||||
return super().keypress(size, key)
|
||||
|
||||
elif self._mode == self.SETTING_NICK:
|
||||
elif self._mode == UiMode.SETTING_NICK:
|
||||
if key == "enter":
|
||||
if self._edit_nick.text:
|
||||
self.nick(self._edit_nick.text)
|
||||
|
|
@ -485,37 +498,62 @@ class RoomWidget(urwid.WidgetWrap):
|
|||
|
||||
# Reacting to euph events
|
||||
|
||||
async def on_snapshot(self, messages: List[yaboli.Message]):
|
||||
async def on_connected(self) -> None:
|
||||
pass
|
||||
|
||||
async def on_snapshot(self, messages: List[yaboli.LiveMessage]) -> None:
|
||||
for message in messages:
|
||||
self.receive_message(message)
|
||||
self.update_tree()
|
||||
|
||||
async def on_send(self, message: yaboli.Message):
|
||||
self.update_nick_list()
|
||||
|
||||
async def on_send(self, message: yaboli.LiveMessage) -> None:
|
||||
self.receive_message(message)
|
||||
self.update_tree()
|
||||
|
||||
async def on_join(self, user: yaboli.LiveSession) -> None:
|
||||
self.update_nick_list()
|
||||
|
||||
async def on_part(self, user: yaboli.LiveSession) -> None:
|
||||
self.update_nick_list()
|
||||
|
||||
async def on_nick(self,
|
||||
user: yaboli.LiveSession,
|
||||
from_: str,
|
||||
to: str,
|
||||
) -> None:
|
||||
|
||||
self.update_nick_list()
|
||||
|
||||
async def on_edit(self, message: yaboli.LiveMessage) -> None:
|
||||
self.receive_message(message)
|
||||
|
||||
async def on_disconnect(self, reason: str) -> None:
|
||||
pass
|
||||
|
||||
# Euph actions
|
||||
|
||||
@synchronous
|
||||
async def request_logs(self):
|
||||
async def request_logs(self) -> None:
|
||||
oldest_id = self._supply.oldest_id()
|
||||
if oldest_id is not None:
|
||||
messages = await self._room.log(self._log_amount, oldest_id)
|
||||
|
||||
if len(messages) == 0:
|
||||
self._hit_top_of_supply = True
|
||||
|
||||
for message in messages:
|
||||
self.receive_message(message)
|
||||
self.update_tree()
|
||||
|
||||
self._requesting_logs = False
|
||||
|
||||
@synchronous
|
||||
async def nick(self, nick: str):
|
||||
new_nick = await self._room.nick(nick)
|
||||
self.own_nick_change()
|
||||
async def nick(self, nick: str) -> None:
|
||||
await self._room.nick(nick)
|
||||
self.change_own_nick()
|
||||
|
||||
@synchronous
|
||||
async def send(self, content: str, parent_id: Optional[str]):
|
||||
async def send(self, content: str, parent_id: Optional[str]) -> None:
|
||||
message = await self._room.send(content, parent_id=parent_id)
|
||||
self.receive_message(message)
|
||||
self.update_tree()
|
||||
|
||||
urwid.register_signal(RoomWidget, ["close"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue