The handhelds' dashboard drops "one minute per dot column"

The activity heading's aside ended "one minute per dot column". The
PicoCalc and the Cardputer draw braille as solid tiles, so there are no
dots there to count, and on 53 columns the words cost the heading its
line. Where braille is solid the aside is "every packet heard" alone;
the axis under the chart still marks the minutes. The desktop keeps it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jean-Pierre MartineauandClaude Opus 5.5 committed 2026-10-04 02:34:36 -04:00
1 parent 00e05e1b8c
commit a8ce329758
2 files changed
+38 -5

No files matched your search

+20 -5
View File
@@ -53,6 +53,7 @@ from ..core.events import MeshEvent
from ..core.models import NODE_TYPE_REPEATER, Observation, utcnow
from ..core.regions import Scope
from ..persistence.repository import OBSERVATION_WINDOW
from ..platforms import Platform, on_platform
from ..services.monitor_service import ACTIVITY_BUCKET_S, ACTIVITY_BUCKETS
from .braillechart import axis_chart, axis_chrome, axis_label_w, meter, timeline_rows
from .packet_viewer import KIND_STYLES, payload_marks
@@ -125,6 +126,24 @@ _GRID_LABEL_W = 9
#: The screen's title, before any scope atom.
_TITLE = "Dashboard — mesh overview"
#: What the whole-mesh activity chart counts, as the heading's aside says it. The desktop
#: adds the chart's unit, ``one minute per dot column``; a font that draws braille solid
#: (the PicoCalc's, the Cardputer's — :attr:`~meshterm.platforms.Platform.solid_braille`)
#: has no dots to count, and on 53 columns the words cost the heading its line
#: (JP, 2026-10-04). The axis under the chart still marks the minutes.
_ACTIVITY_ASIDE = "every packet heard · one minute per dot column"
@on_platform
def _bind_activity_aside(platform: Platform) -> None:
"""Bind the activity heading's aside to the platform's braille (runs now and on switch)."""
global _ACTIVITY_ASIDE
_ACTIVITY_ASIDE = (
"every packet heard"
if platform.solid_braille
else "every packet heard · one minute per dot column"
)
class _ScopeDigest(NamedTuple):
"""One scope view's numbers over the window, in the shapes the sections draw.
@@ -429,11 +448,7 @@ class DashboardScreen(Screen):
heading = Text("Activity", style="accent")
# A narrowed view spends the aside on what it counts, which the reader has to be
# told; the minute per column is on the axis beneath either way.
what = (
"floods in this scope · last 2 h"
if self._scope
else "every packet heard · one minute per dot column"
)
what = "floods in this scope · last 2 h" if self._scope else _ACTIVITY_ASIDE
heading.append(f" · {what}", style="muted")
# Buckets seeded from a previous session's stored history draw grey; only
# what this session heard itself pulses green.
+18
View File
@@ -89,6 +89,24 @@ def test_dashboard_renders_all_three_sections() -> None:
assert "advert" in body and "Alice" in body # traffic class + the busiest node
def test_the_activity_aside_names_dot_columns_only_where_braille_has_dots() -> None:
"""The handhelds draw braille solid, so the heading drops ``one minute per dot column``.
There are no dots there to count, and on 53 columns the words cost the heading its
line. The desktop keeps them; both keep what the chart counts.
"""
from meshterm.platforms import PICOCALC, REGULAR, set_platform
def heading(width: int) -> str:
body = _plain(_screen(histogram=[1] * ACTIVITY_BUCKETS).render_body(width))
return next(line for line in body.splitlines() if "Activity" in line)
set_platform(PICOCALC)
assert heading(53).strip() == "Activity · every packet heard"
set_platform(REGULAR)
assert heading(72).strip() == "Activity · every packet heard · one minute per dot column"
def test_dashboard_activity_chart_reads_newest_right_with_mirrored_scale() -> None:
"""'now' anchors the right edge and the scale marks mirror on both gutters.