The node page shows its map preview again, except on a short frame
A contact's page has enough action rows that, on a 24-row terminal, they left the preview under its five-row floor, and it stepped aside everywhere. It now keeps its floor and the page scrolls. Only a short frame (the Cardputer's 11-row viewport) leaves it out. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ad8792f34b
commit
28529d6b62
2 files changed
+51
-18
No files matched your search
@@ -23,7 +23,7 @@ screen is the node itself, in full:
|
||||
faint ``…`` marks at the edges, the same as a long path line scrolls on the Routes
|
||||
tab. Then, when the node has advertised a location, a static basemap preview (refer
|
||||
to :class:`~meshterm.ui.minimap.MiniMap`) centred on the node. The preview grows into
|
||||
the rows of the viewport that remain.
|
||||
the rows of the viewport that remain. A short frame (the Cardputer) does not show it.
|
||||
|
||||
The actions of the tab: ``Open full map`` opens the full map, centred here, with its
|
||||
find filter set to this node, so the node is lit among the others. Then
|
||||
@@ -884,7 +884,7 @@ class NodeDetailScreen(Screen):
|
||||
if tab is not None:
|
||||
if tab.kind == "info":
|
||||
budget = viewport - len(lines) - action_lines - 1 # the line of the rule
|
||||
lines.extend(self._info_stage(width, budget))
|
||||
lines.extend(self._info_stage(width, budget, short=short))
|
||||
else:
|
||||
route_blocks = [
|
||||
self._route_row_lines(route, i == self._row_index, width)
|
||||
@@ -936,17 +936,18 @@ class NodeDetailScreen(Screen):
|
||||
self._scroll_total = max(1, len(lines))
|
||||
return lines
|
||||
|
||||
def _info_stage(self, width: int, budget: int) -> list[str]:
|
||||
def _info_stage(self, width: int, budget: int, *, short: bool = False) -> list[str]:
|
||||
"""The block of vitals and, with a fix, the location preview grown to fit.
|
||||
|
||||
``budget`` is the number of visible lines that remain for the full stage. The rows
|
||||
of vitals are never truncated. The preview changes its size instead: it takes the
|
||||
lines that the vitals and its caption leave, up to ``_MAP_MAX_ROWS``. When that is
|
||||
less than ``_MAP_MIN_ROWS``, the preview is not shown at all (a short frame keeps
|
||||
its header and actions visible instead). Each row, but not the key, hangs under
|
||||
itself when it wraps. The key keeps its one line and scrolls (refer to
|
||||
:meth:`_key_line`). Thus the row count that sets the size of the preview cannot
|
||||
change while the user scrolls through a long key.
|
||||
lines that the vitals and its caption leave, between ``_MAP_MIN_ROWS`` and
|
||||
``_MAP_MAX_ROWS``. When the vitals leave less than the minimum, the preview keeps
|
||||
its minimum and the page scrolls. On a ``short`` frame, the preview is not shown at
|
||||
all, because its minimum alone pushes the header or the actions off the screen.
|
||||
Each row, but not the key, hangs under itself when it wraps. The key keeps its one
|
||||
line and scrolls (refer to :meth:`_key_line`). Thus the row count that sets the
|
||||
size of the preview cannot change while the user scrolls through a long key.
|
||||
"""
|
||||
lines: list[str] = [""] * tab_air() # the space of the stage under the strip, if any
|
||||
for label, value in self._info_rows:
|
||||
@@ -961,17 +962,16 @@ class NodeDetailScreen(Screen):
|
||||
indent=_LABEL_LANE,
|
||||
)
|
||||
)
|
||||
if self._minimap is not None:
|
||||
# A short frame has no rows for the preview. The 14 rows of the Cardputer leave it
|
||||
# two, and its minimum pushes the identity header and the actions off the screen.
|
||||
if self._minimap is not None and not short:
|
||||
caption = 1 if self._map_caption is not None else 0
|
||||
room = budget - len(lines) - 1 - caption # minus the blank line above it
|
||||
# Below its minimum, the preview is not shown. It does not push the identity
|
||||
# header and the actions off a short frame (the 14 rows of the Cardputer leave
|
||||
# it two).
|
||||
if room >= _MAP_MIN_ROWS:
|
||||
lines.append("")
|
||||
lines.extend(self._minimap.render(width, min(_MAP_MAX_ROWS, room)))
|
||||
if self._map_caption is not None:
|
||||
lines.extend(render_lines(self._map_caption, width, no_wrap=True))
|
||||
rows = max(_MAP_MIN_ROWS, min(_MAP_MAX_ROWS, room))
|
||||
lines.append("")
|
||||
lines.extend(self._minimap.render(width, rows))
|
||||
if self._map_caption is not None:
|
||||
lines.extend(render_lines(self._map_caption, width, no_wrap=True))
|
||||
return lines
|
||||
|
||||
def _key_line(self, label: str, value: Text, width: int) -> str:
|
||||
|
||||
@@ -1369,6 +1369,39 @@ def test_node_detail_screen_tabs_switch_the_stage() -> None:
|
||||
assert screen.picocalc_lyra_lane[2].label == "Info"
|
||||
|
||||
|
||||
def test_node_detail_preview_keeps_its_minimum_except_on_a_short_frame() -> None:
|
||||
"""The preview shows at its minimum when the actions leave less. A short frame has none.
|
||||
|
||||
A contact page has many action rows, so on a terminal of 24 rows they leave the preview
|
||||
less than its minimum. The preview keeps its minimum and the page scrolls. The 11-row
|
||||
viewport of the Cardputer is a short frame, and there the preview is not shown.
|
||||
"""
|
||||
mini = MiniMap(
|
||||
_FakeSession(),
|
||||
_OfflineSource(),
|
||||
14,
|
||||
center_lat=45.5,
|
||||
center_lon=-73.6,
|
||||
zoom=13,
|
||||
markers=[MapMarker(label="Hub", lat=45.5, lon=-73.6, key="3d63aa")],
|
||||
)
|
||||
actions = [_Action(f"a{i}", "⚙", "", f"Action {i}") for i in range(8)]
|
||||
screen = _screen(
|
||||
minimap=mini,
|
||||
map_caption=Text("Hub · centred here", style="faint"),
|
||||
info_actions=actions,
|
||||
)
|
||||
screen.note_viewport(21)
|
||||
body = _plain(screen.render_body(72)).splitlines()
|
||||
caption = next(i for i, line in enumerate(body) if "centred here" in line)
|
||||
vitals = next(i for i, line in enumerate(body) if line.startswith("packets"))
|
||||
assert caption - vitals - 2 >= 5 # the rows between the blank line and the caption
|
||||
assert len(body) > 21 # the preview did not shrink under its minimum: the page scrolls
|
||||
|
||||
screen.note_viewport(11)
|
||||
assert "centred here" not in _plain(screen.render_body(53))
|
||||
|
||||
|
||||
def test_node_detail_single_tab_hides_the_switch_hint() -> None:
|
||||
"""A page with only one tab does not have the ←→ tab atom in its footer."""
|
||||
screen = _screen(tabs=[_Tab("Info", "info")]) # our node: no Routes tab
|
||||
|
||||
Reference in new issue
Block a user