Packet viewer paging walks the feed highlight in step
The viewer reports each navigation through on_navigate and the dashboard follows by re-highlighting that packet in the feed, so closing the viewer lands where the reading left off. Home/End move the highlight to the newest/oldest packet while it is active (plain scroll-to-edge otherwise). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
21c5017706
commit
1205ef211b
2 files changed
+37
-7
No files matched your search
@@ -228,9 +228,17 @@ class DashboardScreen(Screen):
|
||||
elif action in ("pagedown", "space"):
|
||||
self.scroll_pages(1)
|
||||
elif action in ("home", "ctrl_home"):
|
||||
self.scroll_to_top()
|
||||
# With the feed highlight active, Home jumps to the newest packet;
|
||||
# otherwise it keeps its plain scroll-to-top meaning (End mirrors it).
|
||||
if self._selected is not None:
|
||||
self._select_index(0)
|
||||
else:
|
||||
self.scroll_to_top()
|
||||
elif action in ("end", "ctrl_end"):
|
||||
self.scroll_to_bottom()
|
||||
if self._selected is not None:
|
||||
self._select_index(len(self._feed) - 1)
|
||||
else:
|
||||
self.scroll_to_bottom()
|
||||
elif action == "escape":
|
||||
if self._selected is not None:
|
||||
self._selected = None # first Esc peels the highlight, second leaves
|
||||
@@ -243,19 +251,35 @@ class DashboardScreen(Screen):
|
||||
if not self._feed:
|
||||
return
|
||||
if self._selected is None:
|
||||
self._selected = 0
|
||||
self._select_index(0)
|
||||
else:
|
||||
self._selected = max(0, min(self._selected + delta, len(self._feed) - 1))
|
||||
self._select_index(self._selected + delta)
|
||||
|
||||
def _select_index(self, index: int) -> None:
|
||||
"""Highlight one feed row (clamped) and repaint."""
|
||||
self._selected = max(0, min(index, len(self._feed) - 1))
|
||||
self._session.invalidate()
|
||||
|
||||
def _open_packet(self) -> None:
|
||||
"""Float the packet viewer over the highlighted feed row."""
|
||||
"""Float the packet viewer over the highlighted feed row.
|
||||
|
||||
Paging inside the viewer walks the feed highlight in step (via
|
||||
``on_navigate``), so closing it lands back on the packet last viewed.
|
||||
"""
|
||||
if self._selected is None or not self._feed:
|
||||
return
|
||||
|
||||
def follow(entry: PacketEntry) -> None:
|
||||
# The feed may have grown since the snapshot; find the entry itself.
|
||||
for i, candidate in enumerate(self._feed):
|
||||
if candidate is entry:
|
||||
self._select_index(i)
|
||||
return
|
||||
|
||||
viewer = PacketViewer(
|
||||
list(self._feed), self._selected,
|
||||
resolve=self._resolve, prefix_bytes=self._prefix_bytes,
|
||||
self_name=self._self_name,
|
||||
self_name=self._self_name, on_navigate=follow,
|
||||
)
|
||||
asyncio.ensure_future(self._session.run_screen(viewer))
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from typing import Callable, Optional
|
||||
|
||||
from rich.console import RenderableType
|
||||
from rich.table import Table
|
||||
@@ -170,6 +170,7 @@ class PacketViewer(Screen):
|
||||
resolve: NodeResolver,
|
||||
prefix_bytes: int = 0,
|
||||
self_name: Optional[str] = None,
|
||||
on_navigate: Optional[Callable[[PacketEntry], None]] = None,
|
||||
) -> None:
|
||||
"""Open the viewer over a packet list.
|
||||
|
||||
@@ -180,6 +181,8 @@ class PacketViewer(Screen):
|
||||
resolve: Maps a node hash to a friendly name when known.
|
||||
prefix_bytes: Path-hash width to light in displayed hashes (0 = none).
|
||||
self_name: Our own node's name, drawn white wherever it appears.
|
||||
on_navigate: Called with the newly shown entry whenever paging moves the
|
||||
view, so the opening list can walk its own highlight in step.
|
||||
"""
|
||||
super().__init__()
|
||||
self._entries = entries
|
||||
@@ -187,6 +190,7 @@ class PacketViewer(Screen):
|
||||
self._resolve = resolve
|
||||
self._prefix_bytes = prefix_bytes
|
||||
self._self_name = self_name
|
||||
self._on_navigate = on_navigate
|
||||
if len(entries) > 1:
|
||||
self.footer_hint = "PgUp/PgDn newer/older · Home/End ends · Esc close"
|
||||
else:
|
||||
@@ -226,6 +230,8 @@ class PacketViewer(Screen):
|
||||
self._index = index
|
||||
self.scroll = 0
|
||||
self._set_title()
|
||||
if self._on_navigate is not None:
|
||||
self._on_navigate(self._entries[index])
|
||||
|
||||
# --- rendering -------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in new issue
Block a user