app: debounce channel tree and cache render width
This commit is contained in:
@@ -25,6 +25,7 @@ VOLUME_STEPS = (0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0)
|
||||
RECONNECT_INITIAL = 2 # seconds before first retry
|
||||
RECONNECT_MAX = 30 # maximum backoff delay
|
||||
RECONNECT_RETRIES = 10 # attempts before giving up
|
||||
TREE_DEBOUNCE = 0.1 # seconds to coalesce state changes
|
||||
|
||||
|
||||
def _next_volume(current: float) -> float:
|
||||
@@ -186,8 +187,7 @@ class ChannelTree(Static):
|
||||
for child in children:
|
||||
self._collect_order(child.channel_id, order)
|
||||
|
||||
@property
|
||||
def _available_width(self) -> int:
|
||||
def _get_width(self) -> int:
|
||||
"""Usable character width (content area, excludes padding/border)."""
|
||||
w = self.content_size.width
|
||||
if w <= 0:
|
||||
@@ -218,9 +218,10 @@ class ChannelTree(Static):
|
||||
if not self._channels:
|
||||
return " Channels\n [dim]\u2514\u2500 (not connected)[/]"
|
||||
|
||||
w = self._get_width()
|
||||
lines = [" [bold]Channels[/]"]
|
||||
root_id = self._find_root()
|
||||
self._render_tree(root_id, lines, indent=1, is_last=True)
|
||||
self._render_tree(root_id, lines, indent=1, is_last=True, w=w)
|
||||
return "\n".join(lines)
|
||||
|
||||
def _find_root(self) -> int:
|
||||
@@ -235,12 +236,11 @@ class ChannelTree(Static):
|
||||
lines: list[str],
|
||||
indent: int,
|
||||
is_last: bool,
|
||||
w: int,
|
||||
) -> None:
|
||||
ch = self._channels.get(channel_id)
|
||||
if ch is None:
|
||||
return
|
||||
|
||||
w = self._available_width
|
||||
prefix = " " * indent
|
||||
branch = "\u2514\u2500" if is_last else "\u251c\u2500"
|
||||
|
||||
@@ -294,6 +294,7 @@ class ChannelTree(Static):
|
||||
lines,
|
||||
indent + 2,
|
||||
is_last=i == len(children) - 1,
|
||||
w=w,
|
||||
)
|
||||
|
||||
def on_key(self, event: events.Key) -> None:
|
||||
@@ -412,6 +413,7 @@ class TuimbleApp(App):
|
||||
self._audio.input_gain = acfg.input_gain
|
||||
self._audio.output_gain = acfg.output_gain
|
||||
self._pending_reload: Config | None = None
|
||||
self._tree_refresh_timer = None
|
||||
self._reconnecting: bool = False
|
||||
self._reconnect_attempt: int = 0
|
||||
self._intentional_disconnect: bool = False
|
||||
@@ -620,7 +622,11 @@ class TuimbleApp(App):
|
||||
chatlog.write(f"[#7aa2f7]{msg.sender}[/] {clean}")
|
||||
|
||||
def on_server_state_changed(self, _msg: ServerStateChanged) -> None:
|
||||
self._refresh_channel_tree()
|
||||
if self._tree_refresh_timer is not None:
|
||||
self._tree_refresh_timer.stop()
|
||||
self._tree_refresh_timer = self.set_timer(
|
||||
TREE_DEBOUNCE, self._refresh_channel_tree,
|
||||
)
|
||||
|
||||
def on_channel_selected(self, msg: ChannelSelected) -> None:
|
||||
if not self._client.connected:
|
||||
|
||||
Reference in New Issue
Block a user