The community has a page, and the page is its invite

A fourth About page, `Join Discord`, sitting between the author and the ask:
what is this, who made it, where is everyone, how do I help. Like its three
siblings it is written markdown under assets/pages, reads nothing and
transmits nothing, and keeps a CLI face — `meshterm discord`.

It is short on purpose. The invite link, and the code for it in a `qr` fence,
because on a PicoCalc there is no clipboard and the code is how a link leaves
the screen at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jean-Pierre MartineauandClaude Opus 5 committed 2026-09-02 08:38:44 -04:00
1 parent 155c0b5b21
commit 6fc4e7afc9
6 files changed
+74 -15

No files matched your search

+15 -5
View File
@@ -1,4 +1,4 @@
"""About MeshTerm tests: the three pages, their placeholders, and their menu section.
"""About MeshTerm tests: the four pages, their placeholders, and their menu section.
The pages carry no state and no controls, so what is worth pinning is what they *say*
and how they are framed: the live package facts they must never drift from, the
@@ -18,6 +18,7 @@ from meshterm.ui.about import (
AboutPage,
about_author,
about_meshterm,
join_discord,
support_project,
)
@@ -126,18 +127,27 @@ def test_the_licence_section_states_the_terms_and_the_credit_it_owes() -> None:
assert owed in prose, owed
def test_the_discord_page_carries_the_invite_link_and_a_code_to_scan_it_with() -> None:
"""The link is the whole page, and on a console with no clipboard the QR is how it
leaves the screen — so both have to survive the render."""
text = _page(join_discord)
assert "https://discord.gg/AZwe5Uvb3S" in text
assert "█" in text, "the scannable code didn't render"
def test_pages_are_written_markdown_that_ships_with_the_package() -> None:
"""Filling a page in is editing its ``.md`` file — no Python has to follow."""
from meshterm.ui.about import _PAGES
for name in ("about", "author", "support"):
for name in ("about", "author", "discord", "support"):
source = (_PAGES / f"{name}.md").read_text(encoding="utf-8")
assert source.lstrip().startswith("#"), f"{name}.md doesn't open with a heading"
def test_no_package_placeholder_survives_into_the_rendered_page() -> None:
"""The live facts are filled in as the page opens, so none of the braces reach a reader."""
for builder in (about_meshterm, about_author, support_project):
for builder in (about_meshterm, about_author, join_discord, support_project):
text = _page(builder)
assert "{" not in text and "}" not in text, text
@@ -194,7 +204,7 @@ def test_menu_rows_carry_the_icon_and_the_titles_do_not() -> None:
"""Each page has a menu icon; none of it leaks into the title the screen draws."""
from meshterm.tools import get_tool
for name in ("about", "about-author", "support"):
for name in ("about", "about-author", "discord", "support"):
tool = get_tool(name)
assert tool is not None
assert tool.icon, f"{name} has no menu icon"
@@ -211,7 +221,7 @@ def test_every_page_icon_has_a_picocalc_glyph() -> None:
set_platform(PICOCALC)
try:
for name in ("about", "about-author", "support"):
for name in ("about", "about-author", "discord", "support"):
tool = get_tool(name)
assert tool is not None
compact = glyph(tool.icon)
+12 -1
View File
@@ -54,7 +54,13 @@ from meshterm.services.message_paths import Arrival
from meshterm.services.monitor_service import ACTIVITY_BUCKETS
from meshterm.services.records import CATEGORY_BY_ID
from meshterm.services.topology import MeshTopology, build_topology
from meshterm.ui.about import AboutPage, about_author, about_meshterm, support_project
from meshterm.ui.about import (
AboutPage,
about_author,
about_meshterm,
join_discord,
support_project,
)
from meshterm.ui.chat import ChatScreen
from meshterm.ui.contactlist import SORT_COLUMNS, SORT_OPENS_ASCENDING
from meshterm.ui.contacts_screen import ContactsScreen
@@ -493,6 +499,10 @@ def _support_project(cols: int, rows: int) -> Screen:
return AboutPage("Support MeshTerm", support_project())
def _join_discord(cols: int, rows: int) -> Screen:
return AboutPage("Join Discord", join_discord())
_ENTRIES: list[_Entry] = [
_Entry("dashboard", _dashboard),
_Entry("contacts", _contacts),
@@ -515,6 +525,7 @@ _ENTRIES: list[_Entry] = [
_Entry("tx_sweep", _tx_sweep),
_Entry("about_meshterm", _about_meshterm),
_Entry("about_author", _about_author),
_Entry("join_discord", _join_discord),
_Entry("support_project", _support_project),
]
+1 -1
View File
@@ -167,7 +167,7 @@ def test_main_menu_sections_answer_the_menus_own_question() -> None:
"Explore": ["map", "walk", "trace", "trace-path", "records"],
"This node": ["info", "config", "device-actions", "advert"],
"Other nodes": ["repeater-admin", "tx-optimize"],
"About MeshTerm": ["about", "about-author", "support"],
"About MeshTerm": ["about", "about-author", "discord", "support"],
}
# No section is so big it stops being a grouping (the old Mesh bucket held seven of
# nineteen rows), and none is a bucket of one.